rpcrt4/tests: Fix a few more broken tests on NT4.
[wine.git] / dlls / msxml3 / domdoc.c
blob1724093a39e654ce8ffec656ecd1d49889b181a1
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 domdoc *This = impl_from_IPersistStream(iface);
361 HRESULT hr;
362 BSTR xmlString;
364 TRACE("(%p, %p, %d)\n", iface, pStm, fClearDirty);
366 hr = IXMLDOMNode_get_xml( This->node, &xmlString );
367 if(hr == S_OK)
369 DWORD count;
370 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
372 hr = IStream_Write( pStm, xmlString, len, &count );
374 SysFreeString(xmlString);
377 TRACE("ret 0x%08x\n", hr);
379 return hr;
382 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
383 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
385 TRACE("(%p, %p): stub!\n", iface, pcbSize);
386 return E_NOTIMPL;
389 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
391 xmldoc_IPersistStream_QueryInterface,
392 xmldoc_IPersistStream_AddRef,
393 xmldoc_IPersistStream_Release,
394 xmldoc_IPersistStream_GetClassID,
395 xmldoc_IPersistStream_IsDirty,
396 xmldoc_IPersistStream_Load,
397 xmldoc_IPersistStream_Save,
398 xmldoc_IPersistStream_GetSizeMax,
401 /* ISupportErrorInfo interface */
402 static HRESULT WINAPI support_error_QueryInterface(
403 ISupportErrorInfo *iface,
404 REFIID riid, void** ppvObj )
406 domdoc *This = impl_from_ISupportErrorInfo(iface);
407 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
410 static ULONG WINAPI support_error_AddRef(
411 ISupportErrorInfo *iface )
413 domdoc *This = impl_from_ISupportErrorInfo(iface);
414 return IXMLDocument_AddRef((IXMLDocument *)This);
417 static ULONG WINAPI support_error_Release(
418 ISupportErrorInfo *iface )
420 domdoc *This = impl_from_ISupportErrorInfo(iface);
421 return IXMLDocument_Release((IXMLDocument *)This);
424 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
425 ISupportErrorInfo *iface,
426 REFIID riid )
428 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
429 return S_FALSE;
432 static const struct ISupportErrorInfoVtbl support_error_vtbl =
434 support_error_QueryInterface,
435 support_error_AddRef,
436 support_error_Release,
437 support_error_InterfaceSupportsErrorInfo
440 /* IXMLDOMDocument2 interface */
441 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
443 domdoc *This = impl_from_IXMLDOMDocument2( iface );
445 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
447 *ppvObject = NULL;
449 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
450 IsEqualGUID( riid, &IID_IDispatch ) ||
451 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
452 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
454 *ppvObject = iface;
456 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
458 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
460 else if (IsEqualGUID(&IID_IPersistStream, riid))
462 *ppvObject = &(This->lpvtblIPersistStream);
464 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
466 *ppvObject = &(This->lpvtblIObjectWithSite);
468 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
470 *ppvObject = &This->lpvtblISupportErrorInfo;
472 else if(dispex_query_interface(&This->dispex, riid, ppvObject))
474 return *ppvObject ? S_OK : E_NOINTERFACE;
476 else if(IsEqualGUID(&IID_IRunnableObject, riid))
478 TRACE("IID_IRunnableObject not supported returning NULL\n");
479 return E_NOINTERFACE;
481 else
483 FIXME("interface %s not implemented\n", debugstr_guid(riid));
484 return E_NOINTERFACE;
487 IXMLDOMDocument_AddRef( iface );
489 return S_OK;
493 static ULONG WINAPI domdoc_AddRef(
494 IXMLDOMDocument2 *iface )
496 domdoc *This = impl_from_IXMLDOMDocument2( iface );
497 TRACE("%p\n", This );
498 return InterlockedIncrement( &This->ref );
502 static ULONG WINAPI domdoc_Release(
503 IXMLDOMDocument2 *iface )
505 domdoc *This = impl_from_IXMLDOMDocument2( iface );
506 LONG ref;
508 TRACE("%p\n", This );
510 ref = InterlockedDecrement( &This->ref );
511 if ( ref == 0 )
513 if(This->bsc)
514 detach_bsc(This->bsc);
516 if (This->site)
517 IUnknown_Release( This->site );
518 IUnknown_Release( This->node_unk );
519 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
520 if (This->stream) IStream_Release(This->stream);
521 HeapFree( GetProcessHeap(), 0, This );
524 return ref;
527 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
529 domdoc *This = impl_from_IXMLDOMDocument2( iface );
531 TRACE("(%p)->(%p)\n", This, pctinfo);
533 *pctinfo = 1;
535 return S_OK;
538 static HRESULT WINAPI domdoc_GetTypeInfo(
539 IXMLDOMDocument2 *iface,
540 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
542 domdoc *This = impl_from_IXMLDOMDocument2( iface );
543 HRESULT hr;
545 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
547 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
549 return hr;
552 static HRESULT WINAPI domdoc_GetIDsOfNames(
553 IXMLDOMDocument2 *iface,
554 REFIID riid,
555 LPOLESTR* rgszNames,
556 UINT cNames,
557 LCID lcid,
558 DISPID* rgDispId)
560 domdoc *This = impl_from_IXMLDOMDocument2( iface );
561 ITypeInfo *typeinfo;
562 HRESULT hr;
564 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
565 lcid, rgDispId);
567 if(!rgszNames || cNames == 0 || !rgDispId)
568 return E_INVALIDARG;
570 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
571 if(SUCCEEDED(hr))
573 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
574 ITypeInfo_Release(typeinfo);
577 return hr;
581 static HRESULT WINAPI domdoc_Invoke(
582 IXMLDOMDocument2 *iface,
583 DISPID dispIdMember,
584 REFIID riid,
585 LCID lcid,
586 WORD wFlags,
587 DISPPARAMS* pDispParams,
588 VARIANT* pVarResult,
589 EXCEPINFO* pExcepInfo,
590 UINT* puArgErr)
592 domdoc *This = impl_from_IXMLDOMDocument2( iface );
593 ITypeInfo *typeinfo;
594 HRESULT hr;
596 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
597 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
599 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
600 if(SUCCEEDED(hr))
602 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
603 pVarResult, pExcepInfo, puArgErr);
604 ITypeInfo_Release(typeinfo);
607 return hr;
611 static HRESULT WINAPI domdoc_get_nodeName(
612 IXMLDOMDocument2 *iface,
613 BSTR* name )
615 domdoc *This = impl_from_IXMLDOMDocument2( iface );
616 return IXMLDOMNode_get_nodeName( This->node, name );
620 static HRESULT WINAPI domdoc_get_nodeValue(
621 IXMLDOMDocument2 *iface,
622 VARIANT* value )
624 domdoc *This = impl_from_IXMLDOMDocument2( iface );
625 return IXMLDOMNode_get_nodeValue( This->node, value );
629 static HRESULT WINAPI domdoc_put_nodeValue(
630 IXMLDOMDocument2 *iface,
631 VARIANT value)
633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
634 return IXMLDOMNode_put_nodeValue( This->node, value );
638 static HRESULT WINAPI domdoc_get_nodeType(
639 IXMLDOMDocument2 *iface,
640 DOMNodeType* type )
642 domdoc *This = impl_from_IXMLDOMDocument2( iface );
643 return IXMLDOMNode_get_nodeType( This->node, type );
647 static HRESULT WINAPI domdoc_get_parentNode(
648 IXMLDOMDocument2 *iface,
649 IXMLDOMNode** parent )
651 domdoc *This = impl_from_IXMLDOMDocument2( iface );
652 return IXMLDOMNode_get_parentNode( This->node, parent );
656 static HRESULT WINAPI domdoc_get_childNodes(
657 IXMLDOMDocument2 *iface,
658 IXMLDOMNodeList** childList )
660 domdoc *This = impl_from_IXMLDOMDocument2( iface );
661 return IXMLDOMNode_get_childNodes( This->node, childList );
665 static HRESULT WINAPI domdoc_get_firstChild(
666 IXMLDOMDocument2 *iface,
667 IXMLDOMNode** firstChild )
669 domdoc *This = impl_from_IXMLDOMDocument2( iface );
670 return IXMLDOMNode_get_firstChild( This->node, firstChild );
674 static HRESULT WINAPI domdoc_get_lastChild(
675 IXMLDOMDocument2 *iface,
676 IXMLDOMNode** lastChild )
678 domdoc *This = impl_from_IXMLDOMDocument2( iface );
679 return IXMLDOMNode_get_lastChild( This->node, lastChild );
683 static HRESULT WINAPI domdoc_get_previousSibling(
684 IXMLDOMDocument2 *iface,
685 IXMLDOMNode** previousSibling )
687 domdoc *This = impl_from_IXMLDOMDocument2( iface );
688 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
692 static HRESULT WINAPI domdoc_get_nextSibling(
693 IXMLDOMDocument2 *iface,
694 IXMLDOMNode** nextSibling )
696 domdoc *This = impl_from_IXMLDOMDocument2( iface );
697 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
701 static HRESULT WINAPI domdoc_get_attributes(
702 IXMLDOMDocument2 *iface,
703 IXMLDOMNamedNodeMap** attributeMap )
705 domdoc *This = impl_from_IXMLDOMDocument2( iface );
706 return IXMLDOMNode_get_attributes( This->node, attributeMap );
710 static HRESULT WINAPI domdoc_insertBefore(
711 IXMLDOMDocument2 *iface,
712 IXMLDOMNode* newChild,
713 VARIANT refChild,
714 IXMLDOMNode** outNewChild )
716 domdoc *This = impl_from_IXMLDOMDocument2( iface );
717 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
721 static HRESULT WINAPI domdoc_replaceChild(
722 IXMLDOMDocument2 *iface,
723 IXMLDOMNode* newChild,
724 IXMLDOMNode* oldChild,
725 IXMLDOMNode** outOldChild)
727 domdoc *This = impl_from_IXMLDOMDocument2( iface );
728 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
732 static HRESULT WINAPI domdoc_removeChild(
733 IXMLDOMDocument2 *iface,
734 IXMLDOMNode* childNode,
735 IXMLDOMNode** oldChild)
737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
738 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
742 static HRESULT WINAPI domdoc_appendChild(
743 IXMLDOMDocument2 *iface,
744 IXMLDOMNode* newChild,
745 IXMLDOMNode** outNewChild)
747 domdoc *This = impl_from_IXMLDOMDocument2( iface );
748 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
752 static HRESULT WINAPI domdoc_hasChildNodes(
753 IXMLDOMDocument2 *iface,
754 VARIANT_BOOL* hasChild)
756 domdoc *This = impl_from_IXMLDOMDocument2( iface );
757 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
761 static HRESULT WINAPI domdoc_get_ownerDocument(
762 IXMLDOMDocument2 *iface,
763 IXMLDOMDocument** DOMDocument)
765 domdoc *This = impl_from_IXMLDOMDocument2( iface );
766 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
770 static HRESULT WINAPI domdoc_cloneNode(
771 IXMLDOMDocument2 *iface,
772 VARIANT_BOOL deep,
773 IXMLDOMNode** cloneRoot)
775 domdoc *This = impl_from_IXMLDOMDocument2( iface );
776 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
780 static HRESULT WINAPI domdoc_get_nodeTypeString(
781 IXMLDOMDocument2 *iface,
782 BSTR* nodeType )
784 domdoc *This = impl_from_IXMLDOMDocument2( iface );
785 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
789 static HRESULT WINAPI domdoc_get_text(
790 IXMLDOMDocument2 *iface,
791 BSTR* text )
793 domdoc *This = impl_from_IXMLDOMDocument2( iface );
794 return IXMLDOMNode_get_text( This->node, text );
798 static HRESULT WINAPI domdoc_put_text(
799 IXMLDOMDocument2 *iface,
800 BSTR text )
802 domdoc *This = impl_from_IXMLDOMDocument2( iface );
803 return IXMLDOMNode_put_text( This->node, text );
807 static HRESULT WINAPI domdoc_get_specified(
808 IXMLDOMDocument2 *iface,
809 VARIANT_BOOL* isSpecified )
811 domdoc *This = impl_from_IXMLDOMDocument2( iface );
812 return IXMLDOMNode_get_specified( This->node, isSpecified );
816 static HRESULT WINAPI domdoc_get_definition(
817 IXMLDOMDocument2 *iface,
818 IXMLDOMNode** definitionNode )
820 domdoc *This = impl_from_IXMLDOMDocument2( iface );
821 return IXMLDOMNode_get_definition( This->node, definitionNode );
825 static HRESULT WINAPI domdoc_get_nodeTypedValue(
826 IXMLDOMDocument2 *iface,
827 VARIANT* typedValue )
829 domdoc *This = impl_from_IXMLDOMDocument2( iface );
830 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
833 static HRESULT WINAPI domdoc_put_nodeTypedValue(
834 IXMLDOMDocument2 *iface,
835 VARIANT typedValue )
837 domdoc *This = impl_from_IXMLDOMDocument2( iface );
838 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
842 static HRESULT WINAPI domdoc_get_dataType(
843 IXMLDOMDocument2 *iface,
844 VARIANT* dataTypeName )
846 domdoc *This = impl_from_IXMLDOMDocument2( iface );
847 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
851 static HRESULT WINAPI domdoc_put_dataType(
852 IXMLDOMDocument2 *iface,
853 BSTR dataTypeName )
855 domdoc *This = impl_from_IXMLDOMDocument2( iface );
856 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
860 static HRESULT WINAPI domdoc_get_xml(
861 IXMLDOMDocument2 *iface,
862 BSTR* xmlString )
864 domdoc *This = impl_from_IXMLDOMDocument2( iface );
865 return IXMLDOMNode_get_xml( This->node, xmlString );
869 static HRESULT WINAPI domdoc_transformNode(
870 IXMLDOMDocument2 *iface,
871 IXMLDOMNode* styleSheet,
872 BSTR* xmlString )
874 domdoc *This = impl_from_IXMLDOMDocument2( iface );
875 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
879 static HRESULT WINAPI domdoc_selectNodes(
880 IXMLDOMDocument2 *iface,
881 BSTR queryString,
882 IXMLDOMNodeList** resultList )
884 domdoc *This = impl_from_IXMLDOMDocument2( iface );
885 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
889 static HRESULT WINAPI domdoc_selectSingleNode(
890 IXMLDOMDocument2 *iface,
891 BSTR queryString,
892 IXMLDOMNode** resultNode )
894 domdoc *This = impl_from_IXMLDOMDocument2( iface );
895 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
899 static HRESULT WINAPI domdoc_get_parsed(
900 IXMLDOMDocument2 *iface,
901 VARIANT_BOOL* isParsed )
903 domdoc *This = impl_from_IXMLDOMDocument2( iface );
904 return IXMLDOMNode_get_parsed( This->node, isParsed );
908 static HRESULT WINAPI domdoc_get_namespaceURI(
909 IXMLDOMDocument2 *iface,
910 BSTR* namespaceURI )
912 domdoc *This = impl_from_IXMLDOMDocument2( iface );
913 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
917 static HRESULT WINAPI domdoc_get_prefix(
918 IXMLDOMDocument2 *iface,
919 BSTR* prefixString )
921 domdoc *This = impl_from_IXMLDOMDocument2( iface );
922 return IXMLDOMNode_get_prefix( This->node, prefixString );
926 static HRESULT WINAPI domdoc_get_baseName(
927 IXMLDOMDocument2 *iface,
928 BSTR* nameString )
930 domdoc *This = impl_from_IXMLDOMDocument2( iface );
931 return IXMLDOMNode_get_baseName( This->node, nameString );
935 static HRESULT WINAPI domdoc_transformNodeToObject(
936 IXMLDOMDocument2 *iface,
937 IXMLDOMNode* stylesheet,
938 VARIANT outputObject)
940 domdoc *This = impl_from_IXMLDOMDocument2( iface );
941 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
945 static HRESULT WINAPI domdoc_get_doctype(
946 IXMLDOMDocument2 *iface,
947 IXMLDOMDocumentType** documentType )
949 FIXME("\n");
950 return E_NOTIMPL;
954 static HRESULT WINAPI domdoc_get_implementation(
955 IXMLDOMDocument2 *iface,
956 IXMLDOMImplementation** impl )
958 if(!impl)
959 return E_INVALIDARG;
961 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
963 return S_OK;
966 static HRESULT WINAPI domdoc_get_documentElement(
967 IXMLDOMDocument2 *iface,
968 IXMLDOMElement** DOMElement )
970 domdoc *This = impl_from_IXMLDOMDocument2( iface );
971 xmlDocPtr xmldoc = NULL;
972 xmlNodePtr root = NULL;
973 IXMLDOMNode *element_node;
974 HRESULT hr;
976 TRACE("%p %p\n", This, This->node);
978 if(!DOMElement)
979 return E_INVALIDARG;
981 *DOMElement = NULL;
983 xmldoc = get_doc( This );
985 root = xmlDocGetRootElement( xmldoc );
986 if ( !root )
987 return S_FALSE;
989 element_node = create_node( root );
990 if(!element_node) return S_FALSE;
992 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
993 IXMLDOMNode_Release(element_node);
995 return hr;
999 static HRESULT WINAPI domdoc_put_documentElement(
1000 IXMLDOMDocument2 *iface,
1001 IXMLDOMElement* DOMElement )
1003 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1004 IXMLDOMNode *elementNode;
1005 xmlNodePtr oldRoot;
1006 xmlnode *xmlNode;
1007 HRESULT hr;
1009 TRACE("(%p)->(%p)\n", This, DOMElement);
1011 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1012 if(FAILED(hr))
1013 return hr;
1015 xmlNode = impl_from_IXMLDOMNode( elementNode );
1017 if(!xmlNode->node->parent)
1018 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1019 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1021 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1022 IXMLDOMNode_Release( elementNode );
1024 if(oldRoot)
1025 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1027 return S_OK;
1031 static HRESULT WINAPI domdoc_createElement(
1032 IXMLDOMDocument2 *iface,
1033 BSTR tagname,
1034 IXMLDOMElement** element )
1036 xmlNodePtr xmlnode;
1037 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1038 xmlChar *xml_name;
1039 IUnknown *elem_unk;
1040 HRESULT hr;
1042 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1044 xml_name = xmlChar_from_wchar(tagname);
1045 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1046 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1048 TRACE("created xmlptr %p\n", xmlnode);
1049 elem_unk = create_element(xmlnode, NULL);
1050 HeapFree(GetProcessHeap(), 0, xml_name);
1052 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1053 IUnknown_Release(elem_unk);
1054 TRACE("returning %p\n", *element);
1055 return hr;
1059 static HRESULT WINAPI domdoc_createDocumentFragment(
1060 IXMLDOMDocument2 *iface,
1061 IXMLDOMDocumentFragment** docFrag )
1063 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1064 xmlNodePtr xmlnode;
1066 TRACE("%p\n", iface);
1068 if(!docFrag)
1069 return E_INVALIDARG;
1071 *docFrag = NULL;
1073 xmlnode = xmlNewDocFragment(get_doc( This ) );
1075 if(!xmlnode)
1076 return E_FAIL;
1078 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1079 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1081 return S_OK;
1085 static HRESULT WINAPI domdoc_createTextNode(
1086 IXMLDOMDocument2 *iface,
1087 BSTR data,
1088 IXMLDOMText** text )
1090 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1091 xmlNodePtr xmlnode;
1092 xmlChar *xml_content;
1094 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1096 if(!text)
1097 return E_INVALIDARG;
1099 *text = NULL;
1101 xml_content = xmlChar_from_wchar(data);
1102 xmlnode = xmlNewText(xml_content);
1103 HeapFree(GetProcessHeap(), 0, xml_content);
1105 if(!xmlnode)
1106 return E_FAIL;
1108 xmlnode->doc = get_doc( This );
1109 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1111 *text = (IXMLDOMText*)create_text(xmlnode);
1113 return S_OK;
1117 static HRESULT WINAPI domdoc_createComment(
1118 IXMLDOMDocument2 *iface,
1119 BSTR data,
1120 IXMLDOMComment** comment )
1122 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1123 xmlNodePtr xmlnode;
1124 xmlChar *xml_content;
1126 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1128 if(!comment)
1129 return E_INVALIDARG;
1131 *comment = NULL;
1133 xml_content = xmlChar_from_wchar(data);
1134 xmlnode = xmlNewComment(xml_content);
1135 HeapFree(GetProcessHeap(), 0, xml_content);
1137 if(!xmlnode)
1138 return E_FAIL;
1140 xmlnode->doc = get_doc( This );
1141 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1143 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1145 return S_OK;
1149 static HRESULT WINAPI domdoc_createCDATASection(
1150 IXMLDOMDocument2 *iface,
1151 BSTR data,
1152 IXMLDOMCDATASection** cdata )
1154 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1155 xmlNodePtr xmlnode;
1156 xmlChar *xml_content;
1158 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1160 if(!cdata)
1161 return E_INVALIDARG;
1163 *cdata = NULL;
1165 xml_content = xmlChar_from_wchar(data);
1166 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1167 HeapFree(GetProcessHeap(), 0, xml_content);
1169 if(!xmlnode)
1170 return E_FAIL;
1172 xmlnode->doc = get_doc( This );
1173 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1175 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1177 return S_OK;
1181 static HRESULT WINAPI domdoc_createProcessingInstruction(
1182 IXMLDOMDocument2 *iface,
1183 BSTR target,
1184 BSTR data,
1185 IXMLDOMProcessingInstruction** pi )
1187 #ifdef HAVE_XMLNEWDOCPI
1188 xmlNodePtr xmlnode;
1189 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1190 xmlChar *xml_target, *xml_content;
1192 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1194 if(!pi)
1195 return E_INVALIDARG;
1197 if(!target || lstrlenW(target) == 0)
1198 return E_FAIL;
1200 xml_target = xmlChar_from_wchar(target);
1201 xml_content = xmlChar_from_wchar(data);
1203 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1204 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1205 TRACE("created xmlptr %p\n", xmlnode);
1206 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1208 HeapFree(GetProcessHeap(), 0, xml_content);
1209 HeapFree(GetProcessHeap(), 0, xml_target);
1211 return S_OK;
1212 #else
1213 FIXME("Libxml 2.6.15 or greater required.\n");
1214 return E_NOTIMPL;
1215 #endif
1219 static HRESULT WINAPI domdoc_createAttribute(
1220 IXMLDOMDocument2 *iface,
1221 BSTR name,
1222 IXMLDOMAttribute** attribute )
1224 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1225 xmlNodePtr xmlnode;
1226 xmlChar *xml_name;
1228 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1230 if(!attribute)
1231 return E_INVALIDARG;
1233 *attribute = NULL;
1235 xml_name = xmlChar_from_wchar(name);
1236 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1237 HeapFree(GetProcessHeap(), 0, xml_name);
1239 if(!xmlnode)
1240 return E_FAIL;
1242 xmlnode->doc = get_doc( This );
1243 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1245 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1247 return S_OK;
1251 static HRESULT WINAPI domdoc_createEntityReference(
1252 IXMLDOMDocument2 *iface,
1253 BSTR name,
1254 IXMLDOMEntityReference** entityRef )
1256 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1257 xmlNodePtr xmlnode;
1258 xmlChar *xml_name;
1260 TRACE("%p\n", iface);
1262 if(!entityRef)
1263 return E_INVALIDARG;
1265 *entityRef = NULL;
1267 xml_name = xmlChar_from_wchar(name);
1268 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1269 HeapFree(GetProcessHeap(), 0, xml_name);
1271 if(!xmlnode)
1272 return E_FAIL;
1274 xmlnode->doc = get_doc( This );
1275 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1277 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1279 return S_OK;
1283 static HRESULT WINAPI domdoc_getElementsByTagName(
1284 IXMLDOMDocument2 *iface,
1285 BSTR tagName,
1286 IXMLDOMNodeList** resultList )
1288 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1289 LPWSTR szPattern;
1290 HRESULT hr;
1291 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1293 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1294 szPattern[0] = szPattern[1] = '/';
1295 lstrcpyW(szPattern + 2, tagName);
1297 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1298 HeapFree(GetProcessHeap(), 0, szPattern);
1300 return hr;
1303 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1305 VARIANT tmp;
1306 HRESULT hr;
1308 VariantInit(&tmp);
1309 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1310 if(FAILED(hr))
1311 return E_INVALIDARG;
1313 *type = V_I4(&tmp);
1315 return S_OK;
1318 static HRESULT WINAPI domdoc_createNode(
1319 IXMLDOMDocument2 *iface,
1320 VARIANT Type,
1321 BSTR name,
1322 BSTR namespaceURI,
1323 IXMLDOMNode** node )
1325 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1326 DOMNodeType node_type;
1327 xmlNodePtr xmlnode = NULL;
1328 xmlChar *xml_name;
1329 HRESULT hr;
1331 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1333 if(namespaceURI && namespaceURI[0])
1334 FIXME("nodes with namespaces currently not supported.\n");
1336 hr = get_node_type(Type, &node_type);
1337 if(FAILED(hr))
1338 return hr;
1340 TRACE("node_type %d\n", node_type);
1342 xml_name = xmlChar_from_wchar(name);
1344 switch(node_type)
1346 case NODE_ELEMENT:
1347 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1348 *node = create_node(xmlnode);
1349 TRACE("created %p\n", xmlnode);
1350 break;
1351 case NODE_ATTRIBUTE:
1352 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1353 if(xmlnode)
1355 xmlnode->doc = get_doc( This );
1357 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1360 TRACE("created %p\n", xmlnode);
1361 break;
1363 default:
1364 FIXME("unhandled node type %d\n", node_type);
1365 break;
1368 HeapFree(GetProcessHeap(), 0, xml_name);
1370 if(xmlnode && *node)
1372 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1373 return S_OK;
1376 return E_FAIL;
1379 static HRESULT WINAPI domdoc_nodeFromID(
1380 IXMLDOMDocument2 *iface,
1381 BSTR idString,
1382 IXMLDOMNode** node )
1384 FIXME("\n");
1385 return E_NOTIMPL;
1388 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1390 domdoc *This = obj;
1391 xmlDocPtr xmldoc;
1393 xmldoc = doparse( ptr, len );
1394 if(xmldoc) {
1395 xmldoc->_private = create_priv();
1396 return attach_xmldoc(This->node, xmldoc);
1399 return S_OK;
1402 static HRESULT doread( domdoc *This, LPWSTR filename )
1404 bsc_t *bsc;
1405 HRESULT hr;
1407 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1408 if(FAILED(hr))
1409 return hr;
1411 if(This->bsc)
1412 detach_bsc(This->bsc);
1414 This->bsc = bsc;
1415 return S_OK;
1418 static HRESULT WINAPI domdoc_load(
1419 IXMLDOMDocument2 *iface,
1420 VARIANT xmlSource,
1421 VARIANT_BOOL* isSuccessful )
1423 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1424 LPWSTR filename = NULL;
1425 HRESULT hr = S_FALSE;
1426 IXMLDOMDocument2 *pNewDoc = NULL;
1427 IStream *pStream = NULL;
1428 xmlDocPtr xmldoc;
1430 TRACE("type %d\n", V_VT(&xmlSource) );
1432 *isSuccessful = VARIANT_FALSE;
1434 assert( This->node );
1436 switch( V_VT(&xmlSource) )
1438 case VT_BSTR:
1439 filename = V_BSTR(&xmlSource);
1440 break;
1441 case VT_UNKNOWN:
1442 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1443 if(hr == S_OK)
1445 if(pNewDoc)
1447 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1448 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1449 hr = attach_xmldoc(This->node, xmldoc);
1451 if(SUCCEEDED(hr))
1452 *isSuccessful = VARIANT_TRUE;
1454 return hr;
1457 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1458 if(hr == S_OK)
1460 IPersistStream *pDocStream;
1461 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1462 if(hr == S_OK)
1464 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1465 IStream_Release(pStream);
1466 if(hr == S_OK)
1468 *isSuccessful = VARIANT_TRUE;
1470 TRACE("Using ID_IStream to load Document\n");
1471 return S_OK;
1473 else
1475 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1478 else
1480 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1483 else
1485 /* ISequentialStream */
1486 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1488 break;
1489 default:
1490 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1493 TRACE("filename (%s)\n", debugstr_w(filename));
1495 if ( filename )
1497 hr = doread( This, filename );
1499 if ( FAILED(hr) )
1500 This->error = E_FAIL;
1501 else
1503 hr = This->error = S_OK;
1504 *isSuccessful = VARIANT_TRUE;
1508 if(!filename || FAILED(hr)) {
1509 xmldoc = xmlNewDoc(NULL);
1510 xmldoc->_private = create_priv();
1511 hr = attach_xmldoc(This->node, xmldoc);
1512 if(SUCCEEDED(hr))
1513 hr = S_FALSE;
1516 TRACE("ret (%d)\n", hr);
1518 return hr;
1522 static HRESULT WINAPI domdoc_get_readyState(
1523 IXMLDOMDocument2 *iface,
1524 LONG *value )
1526 FIXME("\n");
1527 return E_NOTIMPL;
1531 static HRESULT WINAPI domdoc_get_parseError(
1532 IXMLDOMDocument2 *iface,
1533 IXMLDOMParseError** errorObj )
1535 BSTR error_string = NULL;
1536 static const WCHAR err[] = {'e','r','r','o','r',0};
1537 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1539 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1541 if(This->error)
1542 error_string = SysAllocString(err);
1544 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1545 if(!*errorObj) return E_OUTOFMEMORY;
1546 return S_OK;
1550 static HRESULT WINAPI domdoc_get_url(
1551 IXMLDOMDocument2 *iface,
1552 BSTR* urlString )
1554 FIXME("\n");
1555 return E_NOTIMPL;
1559 static HRESULT WINAPI domdoc_get_async(
1560 IXMLDOMDocument2 *iface,
1561 VARIANT_BOOL* isAsync )
1563 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1565 TRACE("%p <- %d\n", isAsync, This->async);
1566 *isAsync = This->async;
1567 return S_OK;
1571 static HRESULT WINAPI domdoc_put_async(
1572 IXMLDOMDocument2 *iface,
1573 VARIANT_BOOL isAsync )
1575 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1577 TRACE("%d\n", isAsync);
1578 This->async = isAsync;
1579 return S_OK;
1583 static HRESULT WINAPI domdoc_abort(
1584 IXMLDOMDocument2 *iface )
1586 FIXME("\n");
1587 return E_NOTIMPL;
1591 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1593 UINT len, blen = SysStringLen( bstr );
1594 LPSTR str;
1596 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1597 str = HeapAlloc( GetProcessHeap(), 0, len );
1598 if ( !str )
1599 return FALSE;
1600 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1601 *plen = len;
1602 *pstr = str;
1603 return TRUE;
1606 static HRESULT WINAPI domdoc_loadXML(
1607 IXMLDOMDocument2 *iface,
1608 BSTR bstrXML,
1609 VARIANT_BOOL* isSuccessful )
1611 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1612 xmlDocPtr xmldoc = NULL;
1613 char *str;
1614 int len;
1615 HRESULT hr = S_FALSE, hr2;
1617 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1619 assert ( This->node );
1621 if ( isSuccessful )
1623 *isSuccessful = VARIANT_FALSE;
1625 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1627 xmldoc = doparse( str, len );
1628 HeapFree( GetProcessHeap(), 0, str );
1629 if ( !xmldoc )
1630 This->error = E_FAIL;
1631 else
1633 hr = This->error = S_OK;
1634 *isSuccessful = VARIANT_TRUE;
1638 if(!xmldoc)
1639 xmldoc = xmlNewDoc(NULL);
1641 xmldoc->_private = create_priv();
1642 hr2 = attach_xmldoc( This->node, xmldoc );
1643 if( FAILED(hr2) )
1644 hr = hr2;
1646 return hr;
1650 static HRESULT WINAPI domdoc_save(
1651 IXMLDOMDocument2 *iface,
1652 VARIANT destination )
1654 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1655 HANDLE handle;
1656 xmlChar *mem, *p;
1657 int size;
1658 HRESULT ret = S_OK;
1659 DWORD written;
1661 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1662 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1664 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1666 FIXME("Unhandled vt %d\n", V_VT(&destination));
1667 return S_FALSE;
1670 if(V_VT(&destination) == VT_UNKNOWN)
1672 IUnknown *pUnk = V_UNKNOWN(&destination);
1673 IXMLDOMDocument *pDocument;
1675 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1676 if(ret == S_OK)
1678 BSTR bXML;
1679 VARIANT_BOOL bSuccessful;
1681 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1682 if(ret == S_OK)
1684 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1686 SysFreeString(bXML);
1689 IXMLDOMDocument_Release(pDocument);
1692 TRACE("ret %d\n", ret);
1694 return ret;
1697 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1698 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1699 if( handle == INVALID_HANDLE_VALUE )
1701 WARN("failed to create file\n");
1702 return S_FALSE;
1705 xmlDocDumpMemory(get_doc(This), &mem, &size);
1708 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1709 * MSXML adds XML declaration only for processing instruction nodes.
1710 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1712 p = mem;
1713 if(size > 2 && p[0] == '<' && p[1] == '?') {
1714 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1715 p++;
1716 p += 2;
1717 while(p < mem+size && isspace(*p))
1718 p++;
1719 size -= p-mem;
1722 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1724 WARN("write error\n");
1725 ret = S_FALSE;
1728 xmlFree(mem);
1729 CloseHandle(handle);
1730 return ret;
1733 static HRESULT WINAPI domdoc_get_validateOnParse(
1734 IXMLDOMDocument2 *iface,
1735 VARIANT_BOOL* isValidating )
1737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1739 TRACE("%p <- %d\n", isValidating, This->validating);
1740 *isValidating = This->validating;
1741 return S_OK;
1745 static HRESULT WINAPI domdoc_put_validateOnParse(
1746 IXMLDOMDocument2 *iface,
1747 VARIANT_BOOL isValidating )
1749 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1751 TRACE("%d\n", isValidating);
1752 This->validating = isValidating;
1753 return S_OK;
1757 static HRESULT WINAPI domdoc_get_resolveExternals(
1758 IXMLDOMDocument2 *iface,
1759 VARIANT_BOOL* isResolving )
1761 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1763 TRACE("%p <- %d\n", isResolving, This->resolving);
1764 *isResolving = This->resolving;
1765 return S_OK;
1769 static HRESULT WINAPI domdoc_put_resolveExternals(
1770 IXMLDOMDocument2 *iface,
1771 VARIANT_BOOL isResolving )
1773 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1775 TRACE("%d\n", isResolving);
1776 This->resolving = isResolving;
1777 return S_OK;
1781 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1782 IXMLDOMDocument2 *iface,
1783 VARIANT_BOOL* isPreserving )
1785 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1787 TRACE("%p <- %d\n", isPreserving, This->preserving);
1788 *isPreserving = This->preserving;
1789 return S_OK;
1793 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1794 IXMLDOMDocument2 *iface,
1795 VARIANT_BOOL isPreserving )
1797 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1799 TRACE("%d\n", isPreserving);
1800 This->preserving = isPreserving;
1801 return S_OK;
1805 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1806 IXMLDOMDocument2 *iface,
1807 VARIANT readyStateChangeSink )
1809 FIXME("\n");
1810 return E_NOTIMPL;
1814 static HRESULT WINAPI domdoc_put_onDataAvailable(
1815 IXMLDOMDocument2 *iface,
1816 VARIANT onDataAvailableSink )
1818 FIXME("\n");
1819 return E_NOTIMPL;
1822 static HRESULT WINAPI domdoc_put_onTransformNode(
1823 IXMLDOMDocument2 *iface,
1824 VARIANT onTransformNodeSink )
1826 FIXME("\n");
1827 return E_NOTIMPL;
1830 static HRESULT WINAPI domdoc_get_namespaces(
1831 IXMLDOMDocument2* iface,
1832 IXMLDOMSchemaCollection** schemaCollection )
1834 FIXME("\n");
1835 return E_NOTIMPL;
1838 static HRESULT WINAPI domdoc_get_schemas(
1839 IXMLDOMDocument2* iface,
1840 VARIANT* var1 )
1842 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1843 HRESULT hr = S_FALSE;
1844 IXMLDOMSchemaCollection *cur_schema = This->schema;
1846 TRACE("(%p)->(%p)\n", This, var1);
1848 VariantInit(var1); /* Test shows we don't call VariantClear here */
1849 V_VT(var1) = VT_NULL;
1851 if(cur_schema)
1853 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1854 if(SUCCEEDED(hr))
1855 V_VT(var1) = VT_DISPATCH;
1857 return hr;
1860 static HRESULT WINAPI domdoc_putref_schemas(
1861 IXMLDOMDocument2* iface,
1862 VARIANT var1)
1864 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1865 HRESULT hr = E_FAIL;
1866 IXMLDOMSchemaCollection *new_schema = NULL;
1868 FIXME("(%p): semi-stub\n", This);
1869 switch(V_VT(&var1))
1871 case VT_UNKNOWN:
1872 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1873 break;
1875 case VT_DISPATCH:
1876 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1877 break;
1879 case VT_NULL:
1880 case VT_EMPTY:
1881 hr = S_OK;
1882 break;
1884 default:
1885 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1888 if(SUCCEEDED(hr))
1890 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1891 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1894 return hr;
1897 static HRESULT WINAPI domdoc_validate(
1898 IXMLDOMDocument2* iface,
1899 IXMLDOMParseError** err)
1901 FIXME("\n");
1902 return E_NOTIMPL;
1905 static HRESULT WINAPI domdoc_setProperty(
1906 IXMLDOMDocument2* iface,
1907 BSTR p,
1908 VARIANT var)
1910 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1912 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1914 VARIANT varStr;
1915 HRESULT hr;
1916 BSTR bstr;
1918 V_VT(&varStr) = VT_EMPTY;
1919 if (V_VT(&var) != VT_BSTR)
1921 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1922 return hr;
1923 bstr = V_BSTR(&varStr);
1925 else
1926 bstr = V_BSTR(&var);
1928 hr = S_OK;
1929 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1930 This->bUseXPath = TRUE;
1931 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1932 This->bUseXPath = FALSE;
1933 else
1934 hr = E_FAIL;
1936 VariantClear(&varStr);
1937 return hr;
1940 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1941 return E_FAIL;
1944 static HRESULT WINAPI domdoc_getProperty(
1945 IXMLDOMDocument2* iface,
1946 BSTR p,
1947 VARIANT* var)
1949 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1951 if (var == NULL)
1952 return E_INVALIDARG;
1953 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1955 V_VT(var) = VT_BSTR;
1956 if (This->bUseXPath)
1957 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1958 else
1959 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1960 return S_OK;
1963 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1964 return E_FAIL;
1967 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1969 domdoc_QueryInterface,
1970 domdoc_AddRef,
1971 domdoc_Release,
1972 domdoc_GetTypeInfoCount,
1973 domdoc_GetTypeInfo,
1974 domdoc_GetIDsOfNames,
1975 domdoc_Invoke,
1976 domdoc_get_nodeName,
1977 domdoc_get_nodeValue,
1978 domdoc_put_nodeValue,
1979 domdoc_get_nodeType,
1980 domdoc_get_parentNode,
1981 domdoc_get_childNodes,
1982 domdoc_get_firstChild,
1983 domdoc_get_lastChild,
1984 domdoc_get_previousSibling,
1985 domdoc_get_nextSibling,
1986 domdoc_get_attributes,
1987 domdoc_insertBefore,
1988 domdoc_replaceChild,
1989 domdoc_removeChild,
1990 domdoc_appendChild,
1991 domdoc_hasChildNodes,
1992 domdoc_get_ownerDocument,
1993 domdoc_cloneNode,
1994 domdoc_get_nodeTypeString,
1995 domdoc_get_text,
1996 domdoc_put_text,
1997 domdoc_get_specified,
1998 domdoc_get_definition,
1999 domdoc_get_nodeTypedValue,
2000 domdoc_put_nodeTypedValue,
2001 domdoc_get_dataType,
2002 domdoc_put_dataType,
2003 domdoc_get_xml,
2004 domdoc_transformNode,
2005 domdoc_selectNodes,
2006 domdoc_selectSingleNode,
2007 domdoc_get_parsed,
2008 domdoc_get_namespaceURI,
2009 domdoc_get_prefix,
2010 domdoc_get_baseName,
2011 domdoc_transformNodeToObject,
2012 domdoc_get_doctype,
2013 domdoc_get_implementation,
2014 domdoc_get_documentElement,
2015 domdoc_put_documentElement,
2016 domdoc_createElement,
2017 domdoc_createDocumentFragment,
2018 domdoc_createTextNode,
2019 domdoc_createComment,
2020 domdoc_createCDATASection,
2021 domdoc_createProcessingInstruction,
2022 domdoc_createAttribute,
2023 domdoc_createEntityReference,
2024 domdoc_getElementsByTagName,
2025 domdoc_createNode,
2026 domdoc_nodeFromID,
2027 domdoc_load,
2028 domdoc_get_readyState,
2029 domdoc_get_parseError,
2030 domdoc_get_url,
2031 domdoc_get_async,
2032 domdoc_put_async,
2033 domdoc_abort,
2034 domdoc_loadXML,
2035 domdoc_save,
2036 domdoc_get_validateOnParse,
2037 domdoc_put_validateOnParse,
2038 domdoc_get_resolveExternals,
2039 domdoc_put_resolveExternals,
2040 domdoc_get_preserveWhiteSpace,
2041 domdoc_put_preserveWhiteSpace,
2042 domdoc_put_onReadyStateChange,
2043 domdoc_put_onDataAvailable,
2044 domdoc_put_onTransformNode,
2045 domdoc_get_namespaces,
2046 domdoc_get_schemas,
2047 domdoc_putref_schemas,
2048 domdoc_validate,
2049 domdoc_setProperty,
2050 domdoc_getProperty
2053 /* xmldoc implementation of IObjectWithSite */
2054 static HRESULT WINAPI
2055 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2057 domdoc *This = impl_from_IObjectWithSite(iface);
2058 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2061 static ULONG WINAPI
2062 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2064 domdoc *This = impl_from_IObjectWithSite(iface);
2065 return IXMLDocument_AddRef((IXMLDocument *)This);
2068 static ULONG WINAPI
2069 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2071 domdoc *This = impl_from_IObjectWithSite(iface);
2072 return IXMLDocument_Release((IXMLDocument *)This);
2075 static HRESULT WINAPI
2076 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2078 domdoc *This = impl_from_IObjectWithSite(iface);
2080 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2082 if ( !This->site )
2083 return E_FAIL;
2085 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2088 static HRESULT WINAPI
2089 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2091 domdoc *This = impl_from_IObjectWithSite(iface);
2093 TRACE("%p %p\n", iface, punk);
2095 if(!punk)
2097 if(This->site)
2099 IUnknown_Release( This->site );
2100 This->site = NULL;
2103 return S_OK;
2106 if ( punk )
2107 IUnknown_AddRef( punk );
2109 if(This->site)
2110 IUnknown_Release( This->site );
2112 This->site = punk;
2114 return S_OK;
2117 static const IObjectWithSiteVtbl domdocObjectSite =
2119 xmldoc_ObjectWithSite_QueryInterface,
2120 xmldoc_ObjectWithSite_AddRef,
2121 xmldoc_ObjectWithSite_Release,
2122 xmldoc_SetSite,
2123 xmldoc_GetSite,
2126 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2128 domdoc *This = impl_from_IObjectSafety(iface);
2129 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2132 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2134 domdoc *This = impl_from_IObjectSafety(iface);
2135 return IXMLDocument_AddRef((IXMLDocument *)This);
2138 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2140 domdoc *This = impl_from_IObjectSafety(iface);
2141 return IXMLDocument_Release((IXMLDocument *)This);
2144 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2146 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2147 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2149 domdoc *This = impl_from_IObjectSafety(iface);
2151 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2153 if(!pdwSupportedOptions || !pdwEnabledOptions)
2154 return E_POINTER;
2156 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2157 *pdwEnabledOptions = This->safeopt;
2159 return S_OK;
2162 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2163 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2165 domdoc *This = impl_from_IObjectSafety(iface);
2167 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2169 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2170 return E_FAIL;
2172 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2173 return S_OK;
2176 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2177 xmldoc_Safety_QueryInterface,
2178 xmldoc_Safety_AddRef,
2179 xmldoc_Safety_Release,
2180 xmldoc_Safety_GetInterfaceSafetyOptions,
2181 xmldoc_Safety_SetInterfaceSafetyOptions
2185 static const tid_t domdoc_iface_tids[] = {
2186 IXMLDOMNode_tid,
2187 IXMLDOMDocument_tid,
2188 IXMLDOMDocument2_tid,
2191 static dispex_static_data_t domdoc_dispex = {
2192 NULL,
2193 IXMLDOMDocument2_tid,
2194 NULL,
2195 domdoc_iface_tids
2198 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2200 domdoc *doc;
2201 HRESULT hr;
2203 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2204 if( !doc )
2205 return E_OUTOFMEMORY;
2207 doc->lpVtbl = &domdoc_vtbl;
2208 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2209 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2210 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2211 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2212 doc->ref = 1;
2213 doc->async = VARIANT_TRUE;
2214 doc->validating = 0;
2215 doc->resolving = 0;
2216 doc->preserving = 0;
2217 doc->bUseXPath = FALSE;
2218 doc->error = S_OK;
2219 doc->schema = NULL;
2220 doc->stream = NULL;
2221 doc->site = NULL;
2222 doc->safeopt = 0;
2223 doc->bsc = NULL;
2225 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2226 if(!doc->node_unk)
2228 HeapFree(GetProcessHeap(), 0, doc);
2229 return E_FAIL;
2232 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2233 if(FAILED(hr))
2235 IUnknown_Release(doc->node_unk);
2236 HeapFree( GetProcessHeap(), 0, doc );
2237 return E_FAIL;
2240 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2242 /* The ref on doc->node is actually looped back into this object, so release it */
2243 IXMLDOMNode_Release(doc->node);
2245 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2247 TRACE("returning iface %p\n", *document);
2248 return S_OK;
2251 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2253 xmlDocPtr xmldoc;
2254 HRESULT hr;
2256 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2258 xmldoc = xmlNewDoc(NULL);
2259 if(!xmldoc)
2260 return E_OUTOFMEMORY;
2262 xmldoc->_private = create_priv();
2264 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2265 if(FAILED(hr))
2266 xmlFreeDoc(xmldoc);
2268 return hr;
2271 IUnknown* create_domdoc( xmlNodePtr document )
2273 HRESULT hr;
2274 LPVOID pObj = NULL;
2276 TRACE("(%p)\n", document);
2278 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2279 if (FAILED(hr))
2280 return NULL;
2282 return pObj;
2285 #else
2287 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2289 MESSAGE("This program tried to use a DOMDocument object, but\n"
2290 "libxml2 support was not present at compile time.\n");
2291 return E_NOTIMPL;
2294 #endif