msxml3: Fix building with older libxml versions.
[wine.git] / dlls / msxml3 / domdoc.c
blob77d1d2e5466a0664f55a0e891a99fcc161569ff7
1 /*
2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define NONAMELESSUNION
24 #include "config.h"
26 #include <stdarg.h>
27 #include <assert.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "winnls.h"
32 #include "ole2.h"
33 #include "msxml2.h"
34 #include "wininet.h"
35 #include "winreg.h"
36 #include "shlwapi.h"
37 #include "ocidl.h"
38 #include "objsafe.h"
39 #include "dispex.h"
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
48 #ifdef HAVE_LIBXML2
50 #include <libxml/xmlsave.h>
52 /* not defined in older versions */
53 #define XML_SAVE_FORMAT 1
54 #define XML_SAVE_NO_DECL 2
55 #define XML_SAVE_NO_EMPTY 4
56 #define XML_SAVE_NO_XHTML 8
57 #define XML_SAVE_XHTML 16
58 #define XML_SAVE_AS_XML 32
59 #define XML_SAVE_AS_HTML 64
61 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};
62 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
63 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
65 typedef struct _domdoc
67 xmlnode node;
68 const struct IXMLDOMDocument2Vtbl *lpVtbl;
69 const struct IPersistStreamVtbl *lpvtblIPersistStream;
70 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
71 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
72 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
73 LONG ref;
74 VARIANT_BOOL async;
75 VARIANT_BOOL validating;
76 VARIANT_BOOL resolving;
77 VARIANT_BOOL preserving;
78 BOOL bUseXPath;
79 IXMLDOMSchemaCollection *schema;
80 bsc_t *bsc;
81 HRESULT error;
83 /* IPersistStream */
84 IStream *stream;
86 /* IObjectWithSite*/
87 IUnknown *site;
89 /* IObjectSafety */
90 DWORD safeopt;
91 } domdoc;
94 In native windows, the whole lifetime management of XMLDOMNodes is
95 managed automatically using reference counts. Wine emulates that by
96 maintaining a reference count to the document that is increased for
97 each IXMLDOMNode pointer passed out for this document. If all these
98 pointers are gone, the document is unreachable and gets freed, that
99 is, all nodes in the tree of the document get freed.
101 You are able to create nodes that are associated to a document (in
102 fact, in msxml's XMLDOM model, all nodes are associated to a document),
103 but not in the tree of that document, for example using the createFoo
104 functions from IXMLDOMDocument. These nodes do not get cleaned up
105 by libxml, so we have to do it ourselves.
107 To catch these nodes, a list of "orphan nodes" is introduced.
108 It contains pointers to all roots of node trees that are
109 associated with the document without being part of the document
110 tree. All nodes with parent==NULL (except for the document root nodes)
111 should be in the orphan node list of their document. All orphan nodes
112 get freed together with the document itself.
115 typedef struct _xmldoc_priv {
116 LONG refs;
117 struct list orphans;
118 } xmldoc_priv;
120 typedef struct _orphan_entry {
121 struct list entry;
122 xmlNode * node;
123 } orphan_entry;
125 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
127 return doc->_private;
130 static xmldoc_priv * create_priv(void)
132 xmldoc_priv *priv;
133 priv = heap_alloc( sizeof (*priv) );
135 if(priv)
137 priv->refs = 0;
138 list_init( &priv->orphans );
141 return priv;
144 static xmlDocPtr doparse( char *ptr, int len )
146 #ifdef HAVE_XMLREADMEMORY
148 * use xmlReadMemory if possible so we can suppress
149 * writing errors to stderr
151 return xmlReadMemory( ptr, len, NULL, NULL,
152 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
153 #else
154 return xmlParseMemory( ptr, len );
155 #endif
158 LONG xmldoc_add_ref(xmlDocPtr doc)
160 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
161 TRACE("%d\n", ref);
162 return ref;
165 LONG xmldoc_release(xmlDocPtr doc)
167 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
168 LONG ref = InterlockedDecrement(&priv->refs);
169 TRACE("%d\n", ref);
170 if(ref == 0)
172 orphan_entry *orphan, *orphan2;
173 TRACE("freeing docptr %p\n", doc);
175 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
177 xmlFreeNode( orphan->node );
178 heap_free( orphan );
180 heap_free(doc->_private);
182 xmlFreeDoc(doc);
185 return ref;
188 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
190 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
191 orphan_entry *entry;
193 entry = heap_alloc( sizeof (*entry) );
194 if(!entry)
195 return E_OUTOFMEMORY;
197 entry->node = node;
198 list_add_head( &priv->orphans, &entry->entry );
199 return S_OK;
202 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
204 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
205 orphan_entry *entry, *entry2;
207 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
209 if( entry->node == node )
211 list_remove( &entry->entry );
212 heap_free( entry );
213 return S_OK;
217 return S_FALSE;
220 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
222 if(node->node)
223 xmldoc_release(node->node->doc);
225 node->node = (xmlNodePtr) xml;
226 if(node->node)
227 xmldoc_add_ref(node->node->doc);
229 return S_OK;
232 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
234 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
237 static inline xmlDocPtr get_doc( domdoc *This )
239 return (xmlDocPtr)This->node.node;
242 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
244 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
247 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
249 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
252 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
254 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
257 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
259 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
262 /************************************************************************
263 * xmldoc implementation of IPersistStream.
265 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
266 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
268 domdoc *this = impl_from_IPersistStream(iface);
269 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
272 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
273 IPersistStream *iface)
275 domdoc *this = impl_from_IPersistStream(iface);
276 return IXMLDocument_AddRef((IXMLDocument *)this);
279 static ULONG WINAPI xmldoc_IPersistStream_Release(
280 IPersistStream *iface)
282 domdoc *this = impl_from_IPersistStream(iface);
283 return IXMLDocument_Release((IXMLDocument *)this);
286 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
287 IPersistStream *iface, CLSID *classid)
289 TRACE("(%p,%p): stub!\n", iface, classid);
291 if(!classid)
292 return E_POINTER;
294 *classid = CLSID_DOMDocument2;
296 return S_OK;
299 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
300 IPersistStream *iface)
302 domdoc *This = impl_from_IPersistStream(iface);
304 FIXME("(%p->%p): stub!\n", iface, This);
306 return S_FALSE;
309 static HRESULT WINAPI xmldoc_IPersistStream_Load(
310 IPersistStream *iface, LPSTREAM pStm)
312 domdoc *This = impl_from_IPersistStream(iface);
313 HRESULT hr;
314 HGLOBAL hglobal;
315 DWORD read, written, len;
316 BYTE buf[4096];
317 char *ptr;
318 xmlDocPtr xmldoc = NULL;
320 TRACE("(%p, %p)\n", iface, pStm);
322 if (!pStm)
323 return E_INVALIDARG;
325 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
326 if (FAILED(hr))
327 return hr;
331 IStream_Read(pStm, buf, sizeof(buf), &read);
332 hr = IStream_Write(This->stream, buf, read, &written);
333 } while(SUCCEEDED(hr) && written != 0 && read != 0);
335 if (FAILED(hr))
337 ERR("Failed to copy stream\n");
338 return hr;
341 hr = GetHGlobalFromStream(This->stream, &hglobal);
342 if (FAILED(hr))
343 return hr;
345 len = GlobalSize(hglobal);
346 ptr = GlobalLock(hglobal);
347 if (len != 0)
348 xmldoc = parse_xml(ptr, len);
349 GlobalUnlock(hglobal);
351 if (!xmldoc)
353 ERR("Failed to parse xml\n");
354 return E_FAIL;
357 xmldoc->_private = create_priv();
359 return attach_xmldoc( &This->node, xmldoc );
362 static HRESULT WINAPI xmldoc_IPersistStream_Save(
363 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
365 domdoc *This = impl_from_IPersistStream(iface);
366 HRESULT hr;
367 BSTR xmlString;
369 TRACE("(%p, %p, %d)\n", iface, pStm, fClearDirty);
371 hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &xmlString );
372 if(hr == S_OK)
374 DWORD count;
375 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
377 hr = IStream_Write( pStm, xmlString, len, &count );
379 SysFreeString(xmlString);
382 TRACE("ret 0x%08x\n", hr);
384 return hr;
387 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
388 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
390 TRACE("(%p, %p): stub!\n", iface, pcbSize);
391 return E_NOTIMPL;
394 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
396 xmldoc_IPersistStream_QueryInterface,
397 xmldoc_IPersistStream_AddRef,
398 xmldoc_IPersistStream_Release,
399 xmldoc_IPersistStream_GetClassID,
400 xmldoc_IPersistStream_IsDirty,
401 xmldoc_IPersistStream_Load,
402 xmldoc_IPersistStream_Save,
403 xmldoc_IPersistStream_GetSizeMax,
406 /* ISupportErrorInfo interface */
407 static HRESULT WINAPI support_error_QueryInterface(
408 ISupportErrorInfo *iface,
409 REFIID riid, void** ppvObj )
411 domdoc *This = impl_from_ISupportErrorInfo(iface);
412 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
415 static ULONG WINAPI support_error_AddRef(
416 ISupportErrorInfo *iface )
418 domdoc *This = impl_from_ISupportErrorInfo(iface);
419 return IXMLDocument_AddRef((IXMLDocument *)This);
422 static ULONG WINAPI support_error_Release(
423 ISupportErrorInfo *iface )
425 domdoc *This = impl_from_ISupportErrorInfo(iface);
426 return IXMLDocument_Release((IXMLDocument *)This);
429 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
430 ISupportErrorInfo *iface,
431 REFIID riid )
433 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
434 return S_FALSE;
437 static const struct ISupportErrorInfoVtbl support_error_vtbl =
439 support_error_QueryInterface,
440 support_error_AddRef,
441 support_error_Release,
442 support_error_InterfaceSupportsErrorInfo
445 /* IXMLDOMDocument2 interface */
446 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
448 domdoc *This = impl_from_IXMLDOMDocument2( iface );
450 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
452 *ppvObject = NULL;
454 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
455 IsEqualGUID( riid, &IID_IDispatch ) ||
456 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
457 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
459 *ppvObject = iface;
461 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
463 *ppvObject = IXMLDOMNode_from_impl(&This->node);
465 else if (IsEqualGUID(&IID_IPersistStream, riid))
467 *ppvObject = &(This->lpvtblIPersistStream);
469 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
471 *ppvObject = &(This->lpvtblIObjectWithSite);
473 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
475 *ppvObject = &This->lpvtblISupportErrorInfo;
477 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
479 return *ppvObject ? S_OK : E_NOINTERFACE;
481 else if(IsEqualGUID(&IID_IRunnableObject, riid))
483 TRACE("IID_IRunnableObject not supported returning NULL\n");
484 return E_NOINTERFACE;
486 else
488 FIXME("interface %s not implemented\n", debugstr_guid(riid));
489 return E_NOINTERFACE;
492 IUnknown_AddRef((IUnknown*)*ppvObject);
494 return S_OK;
498 static ULONG WINAPI domdoc_AddRef(
499 IXMLDOMDocument2 *iface )
501 domdoc *This = impl_from_IXMLDOMDocument2( iface );
502 TRACE("%p\n", This );
503 return InterlockedIncrement( &This->ref );
507 static ULONG WINAPI domdoc_Release(
508 IXMLDOMDocument2 *iface )
510 domdoc *This = impl_from_IXMLDOMDocument2( iface );
511 LONG ref;
513 TRACE("%p\n", This );
515 ref = InterlockedDecrement( &This->ref );
516 if ( ref == 0 )
518 if(This->bsc)
519 detach_bsc(This->bsc);
521 if (This->site)
522 IUnknown_Release( This->site );
523 destroy_xmlnode(&This->node);
524 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
525 if (This->stream) IStream_Release(This->stream);
526 HeapFree( GetProcessHeap(), 0, This );
529 return ref;
532 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
534 domdoc *This = impl_from_IXMLDOMDocument2( iface );
536 TRACE("(%p)->(%p)\n", This, pctinfo);
538 *pctinfo = 1;
540 return S_OK;
543 static HRESULT WINAPI domdoc_GetTypeInfo(
544 IXMLDOMDocument2 *iface,
545 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
547 domdoc *This = impl_from_IXMLDOMDocument2( iface );
548 HRESULT hr;
550 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
552 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
554 return hr;
557 static HRESULT WINAPI domdoc_GetIDsOfNames(
558 IXMLDOMDocument2 *iface,
559 REFIID riid,
560 LPOLESTR* rgszNames,
561 UINT cNames,
562 LCID lcid,
563 DISPID* rgDispId)
565 domdoc *This = impl_from_IXMLDOMDocument2( iface );
566 ITypeInfo *typeinfo;
567 HRESULT hr;
569 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
570 lcid, rgDispId);
572 if(!rgszNames || cNames == 0 || !rgDispId)
573 return E_INVALIDARG;
575 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
576 if(SUCCEEDED(hr))
578 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
579 ITypeInfo_Release(typeinfo);
582 return hr;
586 static HRESULT WINAPI domdoc_Invoke(
587 IXMLDOMDocument2 *iface,
588 DISPID dispIdMember,
589 REFIID riid,
590 LCID lcid,
591 WORD wFlags,
592 DISPPARAMS* pDispParams,
593 VARIANT* pVarResult,
594 EXCEPINFO* pExcepInfo,
595 UINT* puArgErr)
597 domdoc *This = impl_from_IXMLDOMDocument2( iface );
598 ITypeInfo *typeinfo;
599 HRESULT hr;
601 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
602 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
604 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
605 if(SUCCEEDED(hr))
607 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
608 pVarResult, pExcepInfo, puArgErr);
609 ITypeInfo_Release(typeinfo);
612 return hr;
616 static HRESULT WINAPI domdoc_get_nodeName(
617 IXMLDOMDocument2 *iface,
618 BSTR* name )
620 domdoc *This = impl_from_IXMLDOMDocument2( iface );
621 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
625 static HRESULT WINAPI domdoc_get_nodeValue(
626 IXMLDOMDocument2 *iface,
627 VARIANT* value )
629 domdoc *This = impl_from_IXMLDOMDocument2( iface );
630 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
634 static HRESULT WINAPI domdoc_put_nodeValue(
635 IXMLDOMDocument2 *iface,
636 VARIANT value)
638 domdoc *This = impl_from_IXMLDOMDocument2( iface );
639 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
643 static HRESULT WINAPI domdoc_get_nodeType(
644 IXMLDOMDocument2 *iface,
645 DOMNodeType* type )
647 domdoc *This = impl_from_IXMLDOMDocument2( iface );
648 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
652 static HRESULT WINAPI domdoc_get_parentNode(
653 IXMLDOMDocument2 *iface,
654 IXMLDOMNode** parent )
656 domdoc *This = impl_from_IXMLDOMDocument2( iface );
657 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
661 static HRESULT WINAPI domdoc_get_childNodes(
662 IXMLDOMDocument2 *iface,
663 IXMLDOMNodeList** childList )
665 domdoc *This = impl_from_IXMLDOMDocument2( iface );
666 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
670 static HRESULT WINAPI domdoc_get_firstChild(
671 IXMLDOMDocument2 *iface,
672 IXMLDOMNode** firstChild )
674 domdoc *This = impl_from_IXMLDOMDocument2( iface );
675 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
679 static HRESULT WINAPI domdoc_get_lastChild(
680 IXMLDOMDocument2 *iface,
681 IXMLDOMNode** lastChild )
683 domdoc *This = impl_from_IXMLDOMDocument2( iface );
684 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
688 static HRESULT WINAPI domdoc_get_previousSibling(
689 IXMLDOMDocument2 *iface,
690 IXMLDOMNode** previousSibling )
692 domdoc *This = impl_from_IXMLDOMDocument2( iface );
693 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
697 static HRESULT WINAPI domdoc_get_nextSibling(
698 IXMLDOMDocument2 *iface,
699 IXMLDOMNode** nextSibling )
701 domdoc *This = impl_from_IXMLDOMDocument2( iface );
702 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
706 static HRESULT WINAPI domdoc_get_attributes(
707 IXMLDOMDocument2 *iface,
708 IXMLDOMNamedNodeMap** attributeMap )
710 domdoc *This = impl_from_IXMLDOMDocument2( iface );
711 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
715 static HRESULT WINAPI domdoc_insertBefore(
716 IXMLDOMDocument2 *iface,
717 IXMLDOMNode* newChild,
718 VARIANT refChild,
719 IXMLDOMNode** outNewChild )
721 domdoc *This = impl_from_IXMLDOMDocument2( iface );
722 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
726 static HRESULT WINAPI domdoc_replaceChild(
727 IXMLDOMDocument2 *iface,
728 IXMLDOMNode* newChild,
729 IXMLDOMNode* oldChild,
730 IXMLDOMNode** outOldChild)
732 domdoc *This = impl_from_IXMLDOMDocument2( iface );
733 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
737 static HRESULT WINAPI domdoc_removeChild(
738 IXMLDOMDocument2 *iface,
739 IXMLDOMNode* childNode,
740 IXMLDOMNode** oldChild)
742 domdoc *This = impl_from_IXMLDOMDocument2( iface );
743 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
747 static HRESULT WINAPI domdoc_appendChild(
748 IXMLDOMDocument2 *iface,
749 IXMLDOMNode* newChild,
750 IXMLDOMNode** outNewChild)
752 domdoc *This = impl_from_IXMLDOMDocument2( iface );
753 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
757 static HRESULT WINAPI domdoc_hasChildNodes(
758 IXMLDOMDocument2 *iface,
759 VARIANT_BOOL* hasChild)
761 domdoc *This = impl_from_IXMLDOMDocument2( iface );
762 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
766 static HRESULT WINAPI domdoc_get_ownerDocument(
767 IXMLDOMDocument2 *iface,
768 IXMLDOMDocument** DOMDocument)
770 domdoc *This = impl_from_IXMLDOMDocument2( iface );
771 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
775 static HRESULT WINAPI domdoc_cloneNode(
776 IXMLDOMDocument2 *iface,
777 VARIANT_BOOL deep,
778 IXMLDOMNode** cloneRoot)
780 domdoc *This = impl_from_IXMLDOMDocument2( iface );
781 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
785 static HRESULT WINAPI domdoc_get_nodeTypeString(
786 IXMLDOMDocument2 *iface,
787 BSTR* nodeType )
789 domdoc *This = impl_from_IXMLDOMDocument2( iface );
790 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
794 static HRESULT WINAPI domdoc_get_text(
795 IXMLDOMDocument2 *iface,
796 BSTR* text )
798 domdoc *This = impl_from_IXMLDOMDocument2( iface );
799 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
803 static HRESULT WINAPI domdoc_put_text(
804 IXMLDOMDocument2 *iface,
805 BSTR text )
807 domdoc *This = impl_from_IXMLDOMDocument2( iface );
808 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
812 static HRESULT WINAPI domdoc_get_specified(
813 IXMLDOMDocument2 *iface,
814 VARIANT_BOOL* isSpecified )
816 domdoc *This = impl_from_IXMLDOMDocument2( iface );
817 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
821 static HRESULT WINAPI domdoc_get_definition(
822 IXMLDOMDocument2 *iface,
823 IXMLDOMNode** definitionNode )
825 domdoc *This = impl_from_IXMLDOMDocument2( iface );
826 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
830 static HRESULT WINAPI domdoc_get_nodeTypedValue(
831 IXMLDOMDocument2 *iface,
832 VARIANT* typedValue )
834 domdoc *This = impl_from_IXMLDOMDocument2( iface );
835 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
838 static HRESULT WINAPI domdoc_put_nodeTypedValue(
839 IXMLDOMDocument2 *iface,
840 VARIANT typedValue )
842 domdoc *This = impl_from_IXMLDOMDocument2( iface );
843 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
847 static HRESULT WINAPI domdoc_get_dataType(
848 IXMLDOMDocument2 *iface,
849 VARIANT* dataTypeName )
851 domdoc *This = impl_from_IXMLDOMDocument2( iface );
852 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
856 static HRESULT WINAPI domdoc_put_dataType(
857 IXMLDOMDocument2 *iface,
858 BSTR dataTypeName )
860 domdoc *This = impl_from_IXMLDOMDocument2( iface );
861 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
865 static HRESULT WINAPI domdoc_get_xml(
866 IXMLDOMDocument2 *iface,
867 BSTR* xmlString )
869 domdoc *This = impl_from_IXMLDOMDocument2( iface );
870 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
874 static HRESULT WINAPI domdoc_transformNode(
875 IXMLDOMDocument2 *iface,
876 IXMLDOMNode* styleSheet,
877 BSTR* xmlString )
879 domdoc *This = impl_from_IXMLDOMDocument2( iface );
880 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
884 static HRESULT WINAPI domdoc_selectNodes(
885 IXMLDOMDocument2 *iface,
886 BSTR queryString,
887 IXMLDOMNodeList** resultList )
889 domdoc *This = impl_from_IXMLDOMDocument2( iface );
890 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
894 static HRESULT WINAPI domdoc_selectSingleNode(
895 IXMLDOMDocument2 *iface,
896 BSTR queryString,
897 IXMLDOMNode** resultNode )
899 domdoc *This = impl_from_IXMLDOMDocument2( iface );
900 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
904 static HRESULT WINAPI domdoc_get_parsed(
905 IXMLDOMDocument2 *iface,
906 VARIANT_BOOL* isParsed )
908 domdoc *This = impl_from_IXMLDOMDocument2( iface );
909 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
913 static HRESULT WINAPI domdoc_get_namespaceURI(
914 IXMLDOMDocument2 *iface,
915 BSTR* namespaceURI )
917 domdoc *This = impl_from_IXMLDOMDocument2( iface );
918 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
922 static HRESULT WINAPI domdoc_get_prefix(
923 IXMLDOMDocument2 *iface,
924 BSTR* prefixString )
926 domdoc *This = impl_from_IXMLDOMDocument2( iface );
927 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
931 static HRESULT WINAPI domdoc_get_baseName(
932 IXMLDOMDocument2 *iface,
933 BSTR* nameString )
935 domdoc *This = impl_from_IXMLDOMDocument2( iface );
936 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
940 static HRESULT WINAPI domdoc_transformNodeToObject(
941 IXMLDOMDocument2 *iface,
942 IXMLDOMNode* stylesheet,
943 VARIANT outputObject)
945 domdoc *This = impl_from_IXMLDOMDocument2( iface );
946 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
950 static HRESULT WINAPI domdoc_get_doctype(
951 IXMLDOMDocument2 *iface,
952 IXMLDOMDocumentType** documentType )
954 FIXME("\n");
955 return E_NOTIMPL;
959 static HRESULT WINAPI domdoc_get_implementation(
960 IXMLDOMDocument2 *iface,
961 IXMLDOMImplementation** impl )
963 if(!impl)
964 return E_INVALIDARG;
966 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
968 return S_OK;
971 static HRESULT WINAPI domdoc_get_documentElement(
972 IXMLDOMDocument2 *iface,
973 IXMLDOMElement** DOMElement )
975 domdoc *This = impl_from_IXMLDOMDocument2( iface );
976 xmlDocPtr xmldoc = NULL;
977 xmlNodePtr root = NULL;
978 IXMLDOMNode *element_node;
979 HRESULT hr;
981 TRACE("%p\n", This);
983 if(!DOMElement)
984 return E_INVALIDARG;
986 *DOMElement = NULL;
988 xmldoc = get_doc( This );
990 root = xmlDocGetRootElement( xmldoc );
991 if ( !root )
992 return S_FALSE;
994 element_node = create_node( root );
995 if(!element_node) return S_FALSE;
997 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
998 IXMLDOMNode_Release(element_node);
1000 return hr;
1004 static HRESULT WINAPI domdoc_put_documentElement(
1005 IXMLDOMDocument2 *iface,
1006 IXMLDOMElement* DOMElement )
1008 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1009 IXMLDOMNode *elementNode;
1010 xmlNodePtr oldRoot;
1011 xmlnode *xmlNode;
1012 HRESULT hr;
1014 TRACE("(%p)->(%p)\n", This, DOMElement);
1016 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1017 if(FAILED(hr))
1018 return hr;
1020 xmlNode = impl_from_IXMLDOMNode( elementNode );
1022 if(!xmlNode->node->parent)
1023 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1024 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1026 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1027 IXMLDOMNode_Release( elementNode );
1029 if(oldRoot)
1030 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1032 return S_OK;
1036 static HRESULT WINAPI domdoc_createElement(
1037 IXMLDOMDocument2 *iface,
1038 BSTR tagname,
1039 IXMLDOMElement** element )
1041 xmlNodePtr xmlnode;
1042 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1043 xmlChar *xml_name;
1044 IUnknown *elem_unk;
1045 HRESULT hr;
1047 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1049 xml_name = xmlChar_from_wchar(tagname);
1050 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1051 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1053 TRACE("created xmlptr %p\n", xmlnode);
1054 elem_unk = create_element(xmlnode);
1055 heap_free(xml_name);
1057 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1058 IUnknown_Release(elem_unk);
1059 TRACE("returning %p\n", *element);
1060 return hr;
1064 static HRESULT WINAPI domdoc_createDocumentFragment(
1065 IXMLDOMDocument2 *iface,
1066 IXMLDOMDocumentFragment** docFrag )
1068 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1069 xmlNodePtr xmlnode;
1071 TRACE("%p\n", iface);
1073 if(!docFrag)
1074 return E_INVALIDARG;
1076 *docFrag = NULL;
1078 xmlnode = xmlNewDocFragment(get_doc( This ) );
1080 if(!xmlnode)
1081 return E_FAIL;
1083 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1084 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1086 return S_OK;
1090 static HRESULT WINAPI domdoc_createTextNode(
1091 IXMLDOMDocument2 *iface,
1092 BSTR data,
1093 IXMLDOMText** text )
1095 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1096 xmlNodePtr xmlnode;
1097 xmlChar *xml_content;
1099 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1101 if(!text)
1102 return E_INVALIDARG;
1104 *text = NULL;
1106 xml_content = xmlChar_from_wchar(data);
1107 xmlnode = xmlNewText(xml_content);
1108 heap_free(xml_content);
1110 if(!xmlnode)
1111 return E_FAIL;
1113 xmlnode->doc = get_doc( This );
1114 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1116 *text = (IXMLDOMText*)create_text(xmlnode);
1118 return S_OK;
1122 static HRESULT WINAPI domdoc_createComment(
1123 IXMLDOMDocument2 *iface,
1124 BSTR data,
1125 IXMLDOMComment** comment )
1127 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1128 xmlNodePtr xmlnode;
1129 xmlChar *xml_content;
1131 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1133 if(!comment)
1134 return E_INVALIDARG;
1136 *comment = NULL;
1138 xml_content = xmlChar_from_wchar(data);
1139 xmlnode = xmlNewComment(xml_content);
1140 heap_free(xml_content);
1142 if(!xmlnode)
1143 return E_FAIL;
1145 xmlnode->doc = get_doc( This );
1146 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1148 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1150 return S_OK;
1154 static HRESULT WINAPI domdoc_createCDATASection(
1155 IXMLDOMDocument2 *iface,
1156 BSTR data,
1157 IXMLDOMCDATASection** cdata )
1159 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1160 xmlNodePtr xmlnode;
1161 xmlChar *xml_content;
1163 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1165 if(!cdata)
1166 return E_INVALIDARG;
1168 *cdata = NULL;
1170 xml_content = xmlChar_from_wchar(data);
1171 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1172 heap_free(xml_content);
1174 if(!xmlnode)
1175 return E_FAIL;
1177 xmlnode->doc = get_doc( This );
1178 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1180 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1182 return S_OK;
1186 static HRESULT WINAPI domdoc_createProcessingInstruction(
1187 IXMLDOMDocument2 *iface,
1188 BSTR target,
1189 BSTR data,
1190 IXMLDOMProcessingInstruction** pi )
1192 #ifdef HAVE_XMLNEWDOCPI
1193 xmlNodePtr xmlnode;
1194 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1195 xmlChar *xml_target, *xml_content;
1197 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1199 if(!pi)
1200 return E_INVALIDARG;
1202 if(!target || lstrlenW(target) == 0)
1203 return E_FAIL;
1205 xml_target = xmlChar_from_wchar(target);
1206 xml_content = xmlChar_from_wchar(data);
1208 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1209 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1210 TRACE("created xmlptr %p\n", xmlnode);
1211 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1213 heap_free(xml_content);
1214 heap_free(xml_target);
1216 return S_OK;
1217 #else
1218 FIXME("Libxml 2.6.15 or greater required.\n");
1219 return E_NOTIMPL;
1220 #endif
1224 static HRESULT WINAPI domdoc_createAttribute(
1225 IXMLDOMDocument2 *iface,
1226 BSTR name,
1227 IXMLDOMAttribute** attribute )
1229 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1230 xmlNodePtr xmlnode;
1231 xmlChar *xml_name;
1233 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1235 if(!attribute)
1236 return E_INVALIDARG;
1238 *attribute = NULL;
1240 xml_name = xmlChar_from_wchar(name);
1241 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1242 heap_free(xml_name);
1244 if(!xmlnode)
1245 return E_FAIL;
1247 xmlnode->doc = get_doc( This );
1248 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1250 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1252 return S_OK;
1256 static HRESULT WINAPI domdoc_createEntityReference(
1257 IXMLDOMDocument2 *iface,
1258 BSTR name,
1259 IXMLDOMEntityReference** entityRef )
1261 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1262 xmlNodePtr xmlnode;
1263 xmlChar *xml_name;
1265 TRACE("%p\n", iface);
1267 if(!entityRef)
1268 return E_INVALIDARG;
1270 *entityRef = NULL;
1272 xml_name = xmlChar_from_wchar(name);
1273 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1274 heap_free(xml_name);
1276 if(!xmlnode)
1277 return E_FAIL;
1279 xmlnode->doc = get_doc( This );
1280 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1282 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1284 return S_OK;
1288 static HRESULT WINAPI domdoc_getElementsByTagName(
1289 IXMLDOMDocument2 *iface,
1290 BSTR tagName,
1291 IXMLDOMNodeList** resultList )
1293 static const WCHAR xpathformat[] =
1294 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1295 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1296 LPWSTR szPattern;
1297 HRESULT hr;
1298 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1300 if (tagName[0] == '*' && tagName[1] == 0)
1302 szPattern = heap_alloc(sizeof(WCHAR)*4);
1303 szPattern[0] = szPattern[1] = '/';
1304 szPattern[2] = '*';
1305 szPattern[3] = 0;
1307 else
1309 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1310 wsprintfW(szPattern, xpathformat, tagName);
1313 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1314 heap_free(szPattern);
1316 return hr;
1319 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1321 VARIANT tmp;
1322 HRESULT hr;
1324 VariantInit(&tmp);
1325 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1326 if(FAILED(hr))
1327 return E_INVALIDARG;
1329 *type = V_I4(&tmp);
1331 return S_OK;
1334 static HRESULT WINAPI domdoc_createNode(
1335 IXMLDOMDocument2 *iface,
1336 VARIANT Type,
1337 BSTR name,
1338 BSTR namespaceURI,
1339 IXMLDOMNode** node )
1341 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1342 DOMNodeType node_type;
1343 xmlNodePtr xmlnode = NULL;
1344 xmlChar *xml_name;
1345 HRESULT hr;
1347 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1349 if(namespaceURI && namespaceURI[0])
1350 FIXME("nodes with namespaces currently not supported.\n");
1352 hr = get_node_type(Type, &node_type);
1353 if(FAILED(hr))
1354 return hr;
1356 TRACE("node_type %d\n", node_type);
1358 xml_name = xmlChar_from_wchar(name);
1360 switch(node_type)
1362 case NODE_ELEMENT:
1363 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1364 *node = create_node(xmlnode);
1365 TRACE("created %p\n", xmlnode);
1366 break;
1367 case NODE_ATTRIBUTE:
1368 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1369 if(xmlnode)
1371 xmlnode->doc = get_doc( This );
1373 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1376 TRACE("created %p\n", xmlnode);
1377 break;
1379 default:
1380 FIXME("unhandled node type %d\n", node_type);
1381 break;
1384 heap_free(xml_name);
1386 if(xmlnode && *node)
1388 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1389 return S_OK;
1392 return E_FAIL;
1395 static HRESULT WINAPI domdoc_nodeFromID(
1396 IXMLDOMDocument2 *iface,
1397 BSTR idString,
1398 IXMLDOMNode** node )
1400 FIXME("\n");
1401 return E_NOTIMPL;
1404 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1406 domdoc *This = obj;
1407 xmlDocPtr xmldoc;
1409 xmldoc = doparse( ptr, len );
1410 if(xmldoc) {
1411 xmldoc->_private = create_priv();
1412 return attach_xmldoc(&This->node, xmldoc);
1415 return S_OK;
1418 static HRESULT doread( domdoc *This, LPWSTR filename )
1420 bsc_t *bsc;
1421 HRESULT hr;
1423 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1424 if(FAILED(hr))
1425 return hr;
1427 if(This->bsc)
1428 detach_bsc(This->bsc);
1430 This->bsc = bsc;
1431 return S_OK;
1434 static HRESULT WINAPI domdoc_load(
1435 IXMLDOMDocument2 *iface,
1436 VARIANT xmlSource,
1437 VARIANT_BOOL* isSuccessful )
1439 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1440 LPWSTR filename = NULL;
1441 HRESULT hr = S_FALSE;
1442 IXMLDOMDocument2 *pNewDoc = NULL;
1443 IStream *pStream = NULL;
1444 xmlDocPtr xmldoc;
1446 TRACE("type %d\n", V_VT(&xmlSource) );
1448 *isSuccessful = VARIANT_FALSE;
1450 assert( &This->node );
1452 switch( V_VT(&xmlSource) )
1454 case VT_BSTR:
1455 filename = V_BSTR(&xmlSource);
1456 break;
1457 case VT_UNKNOWN:
1458 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1459 if(hr == S_OK)
1461 if(pNewDoc)
1463 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1464 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1465 hr = attach_xmldoc(&This->node, xmldoc);
1467 if(SUCCEEDED(hr))
1468 *isSuccessful = VARIANT_TRUE;
1470 return hr;
1473 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1474 if(hr == S_OK)
1476 IPersistStream *pDocStream;
1477 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1478 if(hr == S_OK)
1480 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1481 IStream_Release(pStream);
1482 if(hr == S_OK)
1484 *isSuccessful = VARIANT_TRUE;
1486 TRACE("Using ID_IStream to load Document\n");
1487 return S_OK;
1489 else
1491 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1494 else
1496 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1499 else
1501 /* ISequentialStream */
1502 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1504 break;
1505 default:
1506 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1509 TRACE("filename (%s)\n", debugstr_w(filename));
1511 if ( filename )
1513 hr = doread( This, filename );
1515 if ( FAILED(hr) )
1516 This->error = E_FAIL;
1517 else
1519 hr = This->error = S_OK;
1520 *isSuccessful = VARIANT_TRUE;
1524 if(!filename || FAILED(hr)) {
1525 xmldoc = xmlNewDoc(NULL);
1526 xmldoc->_private = create_priv();
1527 hr = attach_xmldoc(&This->node, xmldoc);
1528 if(SUCCEEDED(hr))
1529 hr = S_FALSE;
1532 TRACE("ret (%d)\n", hr);
1534 return hr;
1538 static HRESULT WINAPI domdoc_get_readyState(
1539 IXMLDOMDocument2 *iface,
1540 LONG *value )
1542 FIXME("\n");
1543 return E_NOTIMPL;
1547 static HRESULT WINAPI domdoc_get_parseError(
1548 IXMLDOMDocument2 *iface,
1549 IXMLDOMParseError** errorObj )
1551 BSTR error_string = NULL;
1552 static const WCHAR err[] = {'e','r','r','o','r',0};
1553 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1555 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1557 if(This->error)
1558 error_string = SysAllocString(err);
1560 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1561 if(!*errorObj) return E_OUTOFMEMORY;
1562 return S_OK;
1566 static HRESULT WINAPI domdoc_get_url(
1567 IXMLDOMDocument2 *iface,
1568 BSTR* urlString )
1570 FIXME("\n");
1571 return E_NOTIMPL;
1575 static HRESULT WINAPI domdoc_get_async(
1576 IXMLDOMDocument2 *iface,
1577 VARIANT_BOOL* isAsync )
1579 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1581 TRACE("%p <- %d\n", isAsync, This->async);
1582 *isAsync = This->async;
1583 return S_OK;
1587 static HRESULT WINAPI domdoc_put_async(
1588 IXMLDOMDocument2 *iface,
1589 VARIANT_BOOL isAsync )
1591 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1593 TRACE("%d\n", isAsync);
1594 This->async = isAsync;
1595 return S_OK;
1599 static HRESULT WINAPI domdoc_abort(
1600 IXMLDOMDocument2 *iface )
1602 FIXME("\n");
1603 return E_NOTIMPL;
1607 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1609 UINT len, blen = SysStringLen( bstr );
1610 LPSTR str;
1612 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1613 str = heap_alloc( len );
1614 if ( !str )
1615 return FALSE;
1616 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1617 *plen = len;
1618 *pstr = str;
1619 return TRUE;
1622 static HRESULT WINAPI domdoc_loadXML(
1623 IXMLDOMDocument2 *iface,
1624 BSTR bstrXML,
1625 VARIANT_BOOL* isSuccessful )
1627 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1628 xmlDocPtr xmldoc = NULL;
1629 char *str;
1630 int len;
1631 HRESULT hr = S_FALSE, hr2;
1633 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1635 assert ( &This->node );
1637 if ( isSuccessful )
1639 *isSuccessful = VARIANT_FALSE;
1641 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1643 xmldoc = doparse( str, len );
1644 heap_free( str );
1645 if ( !xmldoc )
1646 This->error = E_FAIL;
1647 else
1649 hr = This->error = S_OK;
1650 *isSuccessful = VARIANT_TRUE;
1654 if(!xmldoc)
1655 xmldoc = xmlNewDoc(NULL);
1657 xmldoc->_private = create_priv();
1658 hr2 = attach_xmldoc( &This->node, xmldoc );
1659 if( FAILED(hr2) )
1660 hr = hr2;
1662 return hr;
1665 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1666 int len)
1668 DWORD written = -1;
1670 if(!WriteFile(ctx, buffer, len, &written, NULL))
1672 WARN("write error\n");
1673 return -1;
1675 else
1676 return written;
1679 static int XMLCALL domdoc_save_closecallback(void *ctx)
1681 return CloseHandle(ctx) ? 0 : -1;
1684 static HRESULT WINAPI domdoc_save(
1685 IXMLDOMDocument2 *iface,
1686 VARIANT destination )
1688 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1689 HANDLE handle;
1690 xmlSaveCtxtPtr ctx;
1691 HRESULT ret = S_OK;
1693 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1694 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1696 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1698 FIXME("Unhandled vt %d\n", V_VT(&destination));
1699 return S_FALSE;
1702 if(V_VT(&destination) == VT_UNKNOWN)
1704 IUnknown *pUnk = V_UNKNOWN(&destination);
1705 IXMLDOMDocument *pDocument;
1707 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1708 if(ret == S_OK)
1710 BSTR bXML;
1711 VARIANT_BOOL bSuccessful;
1713 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1714 if(ret == S_OK)
1716 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1718 SysFreeString(bXML);
1721 IXMLDOMDocument_Release(pDocument);
1724 TRACE("ret %d\n", ret);
1726 return ret;
1729 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1730 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1731 if( handle == INVALID_HANDLE_VALUE )
1733 WARN("failed to create file\n");
1734 return S_FALSE;
1737 /* disable top XML declaration */
1738 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1739 handle, NULL, XML_SAVE_NO_DECL);
1740 if (!ctx)
1742 CloseHandle(handle);
1743 return S_FALSE;
1746 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1747 /* will close file through close callback */
1748 xmlSaveClose(ctx);
1750 return ret;
1753 static HRESULT WINAPI domdoc_get_validateOnParse(
1754 IXMLDOMDocument2 *iface,
1755 VARIANT_BOOL* isValidating )
1757 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1759 TRACE("%p <- %d\n", isValidating, This->validating);
1760 *isValidating = This->validating;
1761 return S_OK;
1765 static HRESULT WINAPI domdoc_put_validateOnParse(
1766 IXMLDOMDocument2 *iface,
1767 VARIANT_BOOL isValidating )
1769 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1771 TRACE("%d\n", isValidating);
1772 This->validating = isValidating;
1773 return S_OK;
1777 static HRESULT WINAPI domdoc_get_resolveExternals(
1778 IXMLDOMDocument2 *iface,
1779 VARIANT_BOOL* isResolving )
1781 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1783 TRACE("%p <- %d\n", isResolving, This->resolving);
1784 *isResolving = This->resolving;
1785 return S_OK;
1789 static HRESULT WINAPI domdoc_put_resolveExternals(
1790 IXMLDOMDocument2 *iface,
1791 VARIANT_BOOL isResolving )
1793 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1795 TRACE("%d\n", isResolving);
1796 This->resolving = isResolving;
1797 return S_OK;
1801 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1802 IXMLDOMDocument2 *iface,
1803 VARIANT_BOOL* isPreserving )
1805 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1807 TRACE("%p <- %d\n", isPreserving, This->preserving);
1808 *isPreserving = This->preserving;
1809 return S_OK;
1813 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1814 IXMLDOMDocument2 *iface,
1815 VARIANT_BOOL isPreserving )
1817 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1819 TRACE("%d\n", isPreserving);
1820 This->preserving = isPreserving;
1821 return S_OK;
1825 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1826 IXMLDOMDocument2 *iface,
1827 VARIANT readyStateChangeSink )
1829 FIXME("\n");
1830 return E_NOTIMPL;
1834 static HRESULT WINAPI domdoc_put_onDataAvailable(
1835 IXMLDOMDocument2 *iface,
1836 VARIANT onDataAvailableSink )
1838 FIXME("\n");
1839 return E_NOTIMPL;
1842 static HRESULT WINAPI domdoc_put_onTransformNode(
1843 IXMLDOMDocument2 *iface,
1844 VARIANT onTransformNodeSink )
1846 FIXME("\n");
1847 return E_NOTIMPL;
1850 static HRESULT WINAPI domdoc_get_namespaces(
1851 IXMLDOMDocument2* iface,
1852 IXMLDOMSchemaCollection** schemaCollection )
1854 FIXME("\n");
1855 return E_NOTIMPL;
1858 static HRESULT WINAPI domdoc_get_schemas(
1859 IXMLDOMDocument2* iface,
1860 VARIANT* var1 )
1862 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1863 HRESULT hr = S_FALSE;
1864 IXMLDOMSchemaCollection *cur_schema = This->schema;
1866 TRACE("(%p)->(%p)\n", This, var1);
1868 VariantInit(var1); /* Test shows we don't call VariantClear here */
1869 V_VT(var1) = VT_NULL;
1871 if(cur_schema)
1873 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1874 if(SUCCEEDED(hr))
1875 V_VT(var1) = VT_DISPATCH;
1877 return hr;
1880 static HRESULT WINAPI domdoc_putref_schemas(
1881 IXMLDOMDocument2* iface,
1882 VARIANT var1)
1884 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1885 HRESULT hr = E_FAIL;
1886 IXMLDOMSchemaCollection *new_schema = NULL;
1888 FIXME("(%p): semi-stub\n", This);
1889 switch(V_VT(&var1))
1891 case VT_UNKNOWN:
1892 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1893 break;
1895 case VT_DISPATCH:
1896 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1897 break;
1899 case VT_NULL:
1900 case VT_EMPTY:
1901 hr = S_OK;
1902 break;
1904 default:
1905 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1908 if(SUCCEEDED(hr))
1910 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1911 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1914 return hr;
1917 static HRESULT WINAPI domdoc_validate(
1918 IXMLDOMDocument2* iface,
1919 IXMLDOMParseError** err)
1921 FIXME("\n");
1922 return E_NOTIMPL;
1925 static HRESULT WINAPI domdoc_setProperty(
1926 IXMLDOMDocument2* iface,
1927 BSTR p,
1928 VARIANT var)
1930 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1932 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1934 VARIANT varStr;
1935 HRESULT hr;
1936 BSTR bstr;
1938 V_VT(&varStr) = VT_EMPTY;
1939 if (V_VT(&var) != VT_BSTR)
1941 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1942 return hr;
1943 bstr = V_BSTR(&varStr);
1945 else
1946 bstr = V_BSTR(&var);
1948 hr = S_OK;
1949 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1950 This->bUseXPath = TRUE;
1951 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1952 This->bUseXPath = FALSE;
1953 else
1954 hr = E_FAIL;
1956 VariantClear(&varStr);
1957 return hr;
1960 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1961 return E_FAIL;
1964 static HRESULT WINAPI domdoc_getProperty(
1965 IXMLDOMDocument2* iface,
1966 BSTR p,
1967 VARIANT* var)
1969 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1971 if (var == NULL)
1972 return E_INVALIDARG;
1973 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1975 V_VT(var) = VT_BSTR;
1976 if (This->bUseXPath)
1977 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1978 else
1979 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1980 return S_OK;
1983 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1984 return E_FAIL;
1987 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1989 domdoc_QueryInterface,
1990 domdoc_AddRef,
1991 domdoc_Release,
1992 domdoc_GetTypeInfoCount,
1993 domdoc_GetTypeInfo,
1994 domdoc_GetIDsOfNames,
1995 domdoc_Invoke,
1996 domdoc_get_nodeName,
1997 domdoc_get_nodeValue,
1998 domdoc_put_nodeValue,
1999 domdoc_get_nodeType,
2000 domdoc_get_parentNode,
2001 domdoc_get_childNodes,
2002 domdoc_get_firstChild,
2003 domdoc_get_lastChild,
2004 domdoc_get_previousSibling,
2005 domdoc_get_nextSibling,
2006 domdoc_get_attributes,
2007 domdoc_insertBefore,
2008 domdoc_replaceChild,
2009 domdoc_removeChild,
2010 domdoc_appendChild,
2011 domdoc_hasChildNodes,
2012 domdoc_get_ownerDocument,
2013 domdoc_cloneNode,
2014 domdoc_get_nodeTypeString,
2015 domdoc_get_text,
2016 domdoc_put_text,
2017 domdoc_get_specified,
2018 domdoc_get_definition,
2019 domdoc_get_nodeTypedValue,
2020 domdoc_put_nodeTypedValue,
2021 domdoc_get_dataType,
2022 domdoc_put_dataType,
2023 domdoc_get_xml,
2024 domdoc_transformNode,
2025 domdoc_selectNodes,
2026 domdoc_selectSingleNode,
2027 domdoc_get_parsed,
2028 domdoc_get_namespaceURI,
2029 domdoc_get_prefix,
2030 domdoc_get_baseName,
2031 domdoc_transformNodeToObject,
2032 domdoc_get_doctype,
2033 domdoc_get_implementation,
2034 domdoc_get_documentElement,
2035 domdoc_put_documentElement,
2036 domdoc_createElement,
2037 domdoc_createDocumentFragment,
2038 domdoc_createTextNode,
2039 domdoc_createComment,
2040 domdoc_createCDATASection,
2041 domdoc_createProcessingInstruction,
2042 domdoc_createAttribute,
2043 domdoc_createEntityReference,
2044 domdoc_getElementsByTagName,
2045 domdoc_createNode,
2046 domdoc_nodeFromID,
2047 domdoc_load,
2048 domdoc_get_readyState,
2049 domdoc_get_parseError,
2050 domdoc_get_url,
2051 domdoc_get_async,
2052 domdoc_put_async,
2053 domdoc_abort,
2054 domdoc_loadXML,
2055 domdoc_save,
2056 domdoc_get_validateOnParse,
2057 domdoc_put_validateOnParse,
2058 domdoc_get_resolveExternals,
2059 domdoc_put_resolveExternals,
2060 domdoc_get_preserveWhiteSpace,
2061 domdoc_put_preserveWhiteSpace,
2062 domdoc_put_onReadyStateChange,
2063 domdoc_put_onDataAvailable,
2064 domdoc_put_onTransformNode,
2065 domdoc_get_namespaces,
2066 domdoc_get_schemas,
2067 domdoc_putref_schemas,
2068 domdoc_validate,
2069 domdoc_setProperty,
2070 domdoc_getProperty
2073 /* xmldoc implementation of IObjectWithSite */
2074 static HRESULT WINAPI
2075 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2077 domdoc *This = impl_from_IObjectWithSite(iface);
2078 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2081 static ULONG WINAPI
2082 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2084 domdoc *This = impl_from_IObjectWithSite(iface);
2085 return IXMLDocument_AddRef((IXMLDocument *)This);
2088 static ULONG WINAPI
2089 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2091 domdoc *This = impl_from_IObjectWithSite(iface);
2092 return IXMLDocument_Release((IXMLDocument *)This);
2095 static HRESULT WINAPI
2096 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2098 domdoc *This = impl_from_IObjectWithSite(iface);
2100 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2102 if ( !This->site )
2103 return E_FAIL;
2105 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2108 static HRESULT WINAPI
2109 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2111 domdoc *This = impl_from_IObjectWithSite(iface);
2113 TRACE("%p %p\n", iface, punk);
2115 if(!punk)
2117 if(This->site)
2119 IUnknown_Release( This->site );
2120 This->site = NULL;
2123 return S_OK;
2126 if ( punk )
2127 IUnknown_AddRef( punk );
2129 if(This->site)
2130 IUnknown_Release( This->site );
2132 This->site = punk;
2134 return S_OK;
2137 static const IObjectWithSiteVtbl domdocObjectSite =
2139 xmldoc_ObjectWithSite_QueryInterface,
2140 xmldoc_ObjectWithSite_AddRef,
2141 xmldoc_ObjectWithSite_Release,
2142 xmldoc_SetSite,
2143 xmldoc_GetSite,
2146 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2148 domdoc *This = impl_from_IObjectSafety(iface);
2149 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2152 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2154 domdoc *This = impl_from_IObjectSafety(iface);
2155 return IXMLDocument_AddRef((IXMLDocument *)This);
2158 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2160 domdoc *This = impl_from_IObjectSafety(iface);
2161 return IXMLDocument_Release((IXMLDocument *)This);
2164 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2166 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2167 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2169 domdoc *This = impl_from_IObjectSafety(iface);
2171 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2173 if(!pdwSupportedOptions || !pdwEnabledOptions)
2174 return E_POINTER;
2176 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2177 *pdwEnabledOptions = This->safeopt;
2179 return S_OK;
2182 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2183 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2185 domdoc *This = impl_from_IObjectSafety(iface);
2187 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2189 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2190 return E_FAIL;
2192 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2193 return S_OK;
2196 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2197 xmldoc_Safety_QueryInterface,
2198 xmldoc_Safety_AddRef,
2199 xmldoc_Safety_Release,
2200 xmldoc_Safety_GetInterfaceSafetyOptions,
2201 xmldoc_Safety_SetInterfaceSafetyOptions
2205 static const tid_t domdoc_iface_tids[] = {
2206 IXMLDOMNode_tid,
2207 IXMLDOMDocument_tid,
2208 IXMLDOMDocument2_tid,
2211 static dispex_static_data_t domdoc_dispex = {
2212 NULL,
2213 IXMLDOMDocument2_tid,
2214 NULL,
2215 domdoc_iface_tids
2218 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2220 domdoc *doc;
2222 doc = heap_alloc( sizeof (*doc) );
2223 if( !doc )
2224 return E_OUTOFMEMORY;
2226 doc->lpVtbl = &domdoc_vtbl;
2227 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2228 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2229 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2230 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2231 doc->ref = 1;
2232 doc->async = VARIANT_TRUE;
2233 doc->validating = 0;
2234 doc->resolving = 0;
2235 doc->preserving = 0;
2236 doc->bUseXPath = FALSE;
2237 doc->error = S_OK;
2238 doc->schema = NULL;
2239 doc->stream = NULL;
2240 doc->site = NULL;
2241 doc->safeopt = 0;
2242 doc->bsc = NULL;
2244 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2246 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2248 TRACE("returning iface %p\n", *document);
2249 return S_OK;
2252 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2254 xmlDocPtr xmldoc;
2255 HRESULT hr;
2257 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2259 xmldoc = xmlNewDoc(NULL);
2260 if(!xmldoc)
2261 return E_OUTOFMEMORY;
2263 xmldoc->_private = create_priv();
2265 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2266 if(FAILED(hr))
2267 xmlFreeDoc(xmldoc);
2269 return hr;
2272 IUnknown* create_domdoc( xmlNodePtr document )
2274 HRESULT hr;
2275 LPVOID pObj = NULL;
2277 TRACE("(%p)\n", document);
2279 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2280 if (FAILED(hr))
2281 return NULL;
2283 return pObj;
2286 #else
2288 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2290 MESSAGE("This program tried to use a DOMDocument object, but\n"
2291 "libxml2 support was not present at compile time.\n");
2292 return E_NOTIMPL;
2295 #endif