push 87b6981010d7405c33b14cddcceec21b47729eba
[wine/hacks.git] / dlls / msxml3 / domdoc.c
blobf3bd371a6f8a2abfd5e1efe5edd062338696b18b
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 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1042 VARIANT type;
1044 TRACE("(%p)->(%s,%p)\n", This, debugstr_w(tagname), element);
1046 if (!element || !tagname) return E_INVALIDARG;
1048 V_VT(&type) = VT_I1;
1049 V_I1(&type) = NODE_ELEMENT;
1051 return IXMLDOMDocument_createNode(iface, type, tagname, NULL, (IXMLDOMNode**)element);
1055 static HRESULT WINAPI domdoc_createDocumentFragment(
1056 IXMLDOMDocument2 *iface,
1057 IXMLDOMDocumentFragment** frag )
1059 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1060 VARIANT type;
1062 TRACE("(%p)->(%p)\n", This, frag);
1064 V_VT(&type) = VT_I1;
1065 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1066 return IXMLDOMDocument_createNode(iface, type, NULL, NULL, (IXMLDOMNode**)frag);
1070 static HRESULT WINAPI domdoc_createTextNode(
1071 IXMLDOMDocument2 *iface,
1072 BSTR data,
1073 IXMLDOMText** text )
1075 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1076 xmlNodePtr xmlnode;
1077 xmlChar *xml_content;
1079 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1081 if(!text)
1082 return E_INVALIDARG;
1084 *text = NULL;
1086 xml_content = xmlChar_from_wchar(data);
1087 xmlnode = xmlNewText(xml_content);
1088 heap_free(xml_content);
1090 if(!xmlnode)
1091 return E_FAIL;
1093 xmlnode->doc = get_doc( This );
1094 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1096 *text = (IXMLDOMText*)create_text(xmlnode);
1098 return S_OK;
1102 static HRESULT WINAPI domdoc_createComment(
1103 IXMLDOMDocument2 *iface,
1104 BSTR data,
1105 IXMLDOMComment** comment )
1107 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1108 xmlNodePtr xmlnode;
1109 xmlChar *xml_content;
1111 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1113 if(!comment)
1114 return E_INVALIDARG;
1116 *comment = NULL;
1118 xml_content = xmlChar_from_wchar(data);
1119 xmlnode = xmlNewComment(xml_content);
1120 heap_free(xml_content);
1122 if(!xmlnode)
1123 return E_FAIL;
1125 xmlnode->doc = get_doc( This );
1126 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1128 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1130 return S_OK;
1134 static HRESULT WINAPI domdoc_createCDATASection(
1135 IXMLDOMDocument2 *iface,
1136 BSTR data,
1137 IXMLDOMCDATASection** cdata )
1139 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1140 xmlNodePtr xmlnode;
1141 xmlChar *xml_content;
1143 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1145 if(!cdata)
1146 return E_INVALIDARG;
1148 *cdata = NULL;
1150 xml_content = xmlChar_from_wchar(data);
1151 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1152 heap_free(xml_content);
1154 if(!xmlnode)
1155 return E_FAIL;
1157 xmlnode->doc = get_doc( This );
1158 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1160 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1162 return S_OK;
1166 static HRESULT WINAPI domdoc_createProcessingInstruction(
1167 IXMLDOMDocument2 *iface,
1168 BSTR target,
1169 BSTR data,
1170 IXMLDOMProcessingInstruction** pi )
1172 #ifdef HAVE_XMLNEWDOCPI
1173 xmlNodePtr xmlnode;
1174 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1175 xmlChar *xml_target, *xml_content;
1177 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1179 if(!pi)
1180 return E_INVALIDARG;
1182 if(!target || lstrlenW(target) == 0)
1183 return E_FAIL;
1185 xml_target = xmlChar_from_wchar(target);
1186 xml_content = xmlChar_from_wchar(data);
1188 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1189 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1190 TRACE("created xmlptr %p\n", xmlnode);
1191 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1193 heap_free(xml_content);
1194 heap_free(xml_target);
1196 return S_OK;
1197 #else
1198 FIXME("Libxml 2.6.15 or greater required.\n");
1199 return E_NOTIMPL;
1200 #endif
1204 static HRESULT WINAPI domdoc_createAttribute(
1205 IXMLDOMDocument2 *iface,
1206 BSTR name,
1207 IXMLDOMAttribute** attribute )
1209 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1210 xmlNodePtr xmlnode;
1211 xmlChar *xml_name;
1213 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1215 if(!attribute)
1216 return E_INVALIDARG;
1218 *attribute = NULL;
1220 xml_name = xmlChar_from_wchar(name);
1221 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1222 heap_free(xml_name);
1224 if(!xmlnode)
1225 return E_FAIL;
1227 xmlnode->doc = get_doc( This );
1228 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1230 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1232 return S_OK;
1236 static HRESULT WINAPI domdoc_createEntityReference(
1237 IXMLDOMDocument2 *iface,
1238 BSTR name,
1239 IXMLDOMEntityReference** entityRef )
1241 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1242 xmlNodePtr xmlnode;
1243 xmlChar *xml_name;
1245 TRACE("%p\n", iface);
1247 if(!entityRef)
1248 return E_INVALIDARG;
1250 *entityRef = NULL;
1252 xml_name = xmlChar_from_wchar(name);
1253 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1254 heap_free(xml_name);
1256 if(!xmlnode)
1257 return E_FAIL;
1259 xmlnode->doc = get_doc( This );
1260 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1262 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1264 return S_OK;
1268 static HRESULT WINAPI domdoc_getElementsByTagName(
1269 IXMLDOMDocument2 *iface,
1270 BSTR tagName,
1271 IXMLDOMNodeList** resultList )
1273 static const WCHAR xpathformat[] =
1274 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1275 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1276 LPWSTR szPattern;
1277 HRESULT hr;
1278 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1280 if (tagName[0] == '*' && tagName[1] == 0)
1282 szPattern = heap_alloc(sizeof(WCHAR)*4);
1283 szPattern[0] = szPattern[1] = '/';
1284 szPattern[2] = '*';
1285 szPattern[3] = 0;
1287 else
1289 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1290 wsprintfW(szPattern, xpathformat, tagName);
1293 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1294 heap_free(szPattern);
1296 return hr;
1299 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1301 VARIANT tmp;
1302 HRESULT hr;
1304 VariantInit(&tmp);
1305 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1306 if(FAILED(hr))
1307 return E_INVALIDARG;
1309 *type = V_I4(&tmp);
1311 return S_OK;
1314 static HRESULT WINAPI domdoc_createNode(
1315 IXMLDOMDocument2 *iface,
1316 VARIANT Type,
1317 BSTR name,
1318 BSTR namespaceURI,
1319 IXMLDOMNode** node )
1321 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1322 DOMNodeType node_type;
1323 xmlNodePtr xmlnode;
1324 xmlChar *xml_name;
1325 HRESULT hr;
1327 TRACE("(%p)->(%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1329 if(!node) return E_INVALIDARG;
1331 if(namespaceURI && namespaceURI[0])
1332 FIXME("nodes with namespaces currently not supported.\n");
1334 hr = get_node_type(Type, &node_type);
1335 if(FAILED(hr)) return hr;
1337 TRACE("node_type %d\n", node_type);
1339 if ((!name || SysStringLen(name) == 0) && (node_type == NODE_ELEMENT))
1340 return E_FAIL;
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 break;
1349 case NODE_ATTRIBUTE:
1350 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1351 break;
1352 case NODE_TEXT:
1353 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1354 break;
1355 case NODE_CDATA_SECTION:
1356 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1357 break;
1358 case NODE_PROCESSING_INSTRUCTION:
1359 #ifdef HAVE_XMLNEWDOCPI
1360 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1361 #else
1362 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1363 xmlnode = NULL;
1364 #endif
1365 break;
1366 case NODE_COMMENT:
1367 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1368 break;
1369 case NODE_DOCUMENT_FRAGMENT:
1370 xmlnode = xmlNewDocFragment(get_doc(This));
1371 break;
1372 /* unsupported types */
1373 case NODE_DOCUMENT:
1374 case NODE_DOCUMENT_TYPE:
1375 case NODE_ENTITY:
1376 case NODE_NOTATION:
1377 heap_free(xml_name);
1378 return E_INVALIDARG;
1379 default:
1380 FIXME("unhandled node type %d\n", node_type);
1381 xmlnode = NULL;
1382 break;
1385 *node = create_node(xmlnode);
1386 heap_free(xml_name);
1388 if(*node)
1390 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1391 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1392 return S_OK;
1395 return E_FAIL;
1398 static HRESULT WINAPI domdoc_nodeFromID(
1399 IXMLDOMDocument2 *iface,
1400 BSTR idString,
1401 IXMLDOMNode** node )
1403 FIXME("\n");
1404 return E_NOTIMPL;
1407 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1409 domdoc *This = obj;
1410 xmlDocPtr xmldoc;
1412 xmldoc = doparse( ptr, len );
1413 if(xmldoc) {
1414 xmldoc->_private = create_priv();
1415 return attach_xmldoc(&This->node, xmldoc);
1418 return S_OK;
1421 static HRESULT doread( domdoc *This, LPWSTR filename )
1423 bsc_t *bsc;
1424 HRESULT hr;
1426 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1427 if(FAILED(hr))
1428 return hr;
1430 if(This->bsc)
1431 detach_bsc(This->bsc);
1433 This->bsc = bsc;
1434 return S_OK;
1437 static HRESULT WINAPI domdoc_load(
1438 IXMLDOMDocument2 *iface,
1439 VARIANT xmlSource,
1440 VARIANT_BOOL* isSuccessful )
1442 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1443 LPWSTR filename = NULL;
1444 HRESULT hr = S_FALSE;
1445 IXMLDOMDocument2 *pNewDoc = NULL;
1446 IStream *pStream = NULL;
1447 xmlDocPtr xmldoc;
1449 TRACE("type %d\n", V_VT(&xmlSource) );
1451 *isSuccessful = VARIANT_FALSE;
1453 assert( &This->node );
1455 switch( V_VT(&xmlSource) )
1457 case VT_BSTR:
1458 filename = V_BSTR(&xmlSource);
1459 break;
1460 case VT_UNKNOWN:
1461 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1462 if(hr == S_OK)
1464 if(pNewDoc)
1466 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1467 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1468 hr = attach_xmldoc(&This->node, xmldoc);
1470 if(SUCCEEDED(hr))
1471 *isSuccessful = VARIANT_TRUE;
1473 return hr;
1476 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1477 if(hr == S_OK)
1479 IPersistStream *pDocStream;
1480 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1481 if(hr == S_OK)
1483 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1484 IStream_Release(pStream);
1485 if(hr == S_OK)
1487 *isSuccessful = VARIANT_TRUE;
1489 TRACE("Using ID_IStream to load Document\n");
1490 return S_OK;
1492 else
1494 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1497 else
1499 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1502 else
1504 /* ISequentialStream */
1505 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1507 break;
1508 default:
1509 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1512 TRACE("filename (%s)\n", debugstr_w(filename));
1514 if ( filename )
1516 hr = doread( This, filename );
1518 if ( FAILED(hr) )
1519 This->error = E_FAIL;
1520 else
1522 hr = This->error = S_OK;
1523 *isSuccessful = VARIANT_TRUE;
1527 if(!filename || FAILED(hr)) {
1528 xmldoc = xmlNewDoc(NULL);
1529 xmldoc->_private = create_priv();
1530 hr = attach_xmldoc(&This->node, xmldoc);
1531 if(SUCCEEDED(hr))
1532 hr = S_FALSE;
1535 TRACE("ret (%d)\n", hr);
1537 return hr;
1541 static HRESULT WINAPI domdoc_get_readyState(
1542 IXMLDOMDocument2 *iface,
1543 LONG *value )
1545 FIXME("\n");
1546 return E_NOTIMPL;
1550 static HRESULT WINAPI domdoc_get_parseError(
1551 IXMLDOMDocument2 *iface,
1552 IXMLDOMParseError** errorObj )
1554 BSTR error_string = NULL;
1555 static const WCHAR err[] = {'e','r','r','o','r',0};
1556 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1558 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1560 if(This->error)
1561 error_string = SysAllocString(err);
1563 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1564 if(!*errorObj) return E_OUTOFMEMORY;
1565 return S_OK;
1569 static HRESULT WINAPI domdoc_get_url(
1570 IXMLDOMDocument2 *iface,
1571 BSTR* urlString )
1573 FIXME("\n");
1574 return E_NOTIMPL;
1578 static HRESULT WINAPI domdoc_get_async(
1579 IXMLDOMDocument2 *iface,
1580 VARIANT_BOOL* isAsync )
1582 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1584 TRACE("%p <- %d\n", isAsync, This->async);
1585 *isAsync = This->async;
1586 return S_OK;
1590 static HRESULT WINAPI domdoc_put_async(
1591 IXMLDOMDocument2 *iface,
1592 VARIANT_BOOL isAsync )
1594 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1596 TRACE("%d\n", isAsync);
1597 This->async = isAsync;
1598 return S_OK;
1602 static HRESULT WINAPI domdoc_abort(
1603 IXMLDOMDocument2 *iface )
1605 FIXME("\n");
1606 return E_NOTIMPL;
1610 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1612 UINT len, blen = SysStringLen( bstr );
1613 LPSTR str;
1615 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1616 str = heap_alloc( len );
1617 if ( !str )
1618 return FALSE;
1619 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1620 *plen = len;
1621 *pstr = str;
1622 return TRUE;
1625 static HRESULT WINAPI domdoc_loadXML(
1626 IXMLDOMDocument2 *iface,
1627 BSTR bstrXML,
1628 VARIANT_BOOL* isSuccessful )
1630 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1631 xmlDocPtr xmldoc = NULL;
1632 char *str;
1633 int len;
1634 HRESULT hr = S_FALSE, hr2;
1636 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1638 assert ( &This->node );
1640 if ( isSuccessful )
1642 *isSuccessful = VARIANT_FALSE;
1644 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1646 xmldoc = doparse( str, len );
1647 heap_free( str );
1648 if ( !xmldoc )
1649 This->error = E_FAIL;
1650 else
1652 hr = This->error = S_OK;
1653 *isSuccessful = VARIANT_TRUE;
1657 if(!xmldoc)
1658 xmldoc = xmlNewDoc(NULL);
1660 xmldoc->_private = create_priv();
1661 hr2 = attach_xmldoc( &This->node, xmldoc );
1662 if( FAILED(hr2) )
1663 hr = hr2;
1665 return hr;
1668 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1669 int len)
1671 DWORD written = -1;
1673 if(!WriteFile(ctx, buffer, len, &written, NULL))
1675 WARN("write error\n");
1676 return -1;
1678 else
1679 return written;
1682 static int XMLCALL domdoc_save_closecallback(void *ctx)
1684 return CloseHandle(ctx) ? 0 : -1;
1687 static HRESULT WINAPI domdoc_save(
1688 IXMLDOMDocument2 *iface,
1689 VARIANT destination )
1691 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1692 HANDLE handle;
1693 xmlSaveCtxtPtr ctx;
1694 HRESULT ret = S_OK;
1696 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1697 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1699 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1701 FIXME("Unhandled vt %d\n", V_VT(&destination));
1702 return S_FALSE;
1705 if(V_VT(&destination) == VT_UNKNOWN)
1707 IUnknown *pUnk = V_UNKNOWN(&destination);
1708 IXMLDOMDocument *pDocument;
1710 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1711 if(ret == S_OK)
1713 BSTR bXML;
1714 VARIANT_BOOL bSuccessful;
1716 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1717 if(ret == S_OK)
1719 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1721 SysFreeString(bXML);
1724 IXMLDOMDocument_Release(pDocument);
1727 TRACE("ret %d\n", ret);
1729 return ret;
1732 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1733 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1734 if( handle == INVALID_HANDLE_VALUE )
1736 WARN("failed to create file\n");
1737 return S_FALSE;
1740 /* disable top XML declaration */
1741 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1742 handle, NULL, XML_SAVE_NO_DECL);
1743 if (!ctx)
1745 CloseHandle(handle);
1746 return S_FALSE;
1749 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1750 /* will close file through close callback */
1751 xmlSaveClose(ctx);
1753 return ret;
1756 static HRESULT WINAPI domdoc_get_validateOnParse(
1757 IXMLDOMDocument2 *iface,
1758 VARIANT_BOOL* isValidating )
1760 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1762 TRACE("%p <- %d\n", isValidating, This->validating);
1763 *isValidating = This->validating;
1764 return S_OK;
1768 static HRESULT WINAPI domdoc_put_validateOnParse(
1769 IXMLDOMDocument2 *iface,
1770 VARIANT_BOOL isValidating )
1772 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1774 TRACE("%d\n", isValidating);
1775 This->validating = isValidating;
1776 return S_OK;
1780 static HRESULT WINAPI domdoc_get_resolveExternals(
1781 IXMLDOMDocument2 *iface,
1782 VARIANT_BOOL* isResolving )
1784 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1786 TRACE("%p <- %d\n", isResolving, This->resolving);
1787 *isResolving = This->resolving;
1788 return S_OK;
1792 static HRESULT WINAPI domdoc_put_resolveExternals(
1793 IXMLDOMDocument2 *iface,
1794 VARIANT_BOOL isResolving )
1796 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1798 TRACE("%d\n", isResolving);
1799 This->resolving = isResolving;
1800 return S_OK;
1804 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1805 IXMLDOMDocument2 *iface,
1806 VARIANT_BOOL* isPreserving )
1808 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1810 TRACE("%p <- %d\n", isPreserving, This->preserving);
1811 *isPreserving = This->preserving;
1812 return S_OK;
1816 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1817 IXMLDOMDocument2 *iface,
1818 VARIANT_BOOL isPreserving )
1820 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1822 TRACE("%d\n", isPreserving);
1823 This->preserving = isPreserving;
1824 return S_OK;
1828 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1829 IXMLDOMDocument2 *iface,
1830 VARIANT readyStateChangeSink )
1832 FIXME("\n");
1833 return E_NOTIMPL;
1837 static HRESULT WINAPI domdoc_put_onDataAvailable(
1838 IXMLDOMDocument2 *iface,
1839 VARIANT onDataAvailableSink )
1841 FIXME("\n");
1842 return E_NOTIMPL;
1845 static HRESULT WINAPI domdoc_put_onTransformNode(
1846 IXMLDOMDocument2 *iface,
1847 VARIANT onTransformNodeSink )
1849 FIXME("\n");
1850 return E_NOTIMPL;
1853 static HRESULT WINAPI domdoc_get_namespaces(
1854 IXMLDOMDocument2* iface,
1855 IXMLDOMSchemaCollection** schemaCollection )
1857 FIXME("\n");
1858 return E_NOTIMPL;
1861 static HRESULT WINAPI domdoc_get_schemas(
1862 IXMLDOMDocument2* iface,
1863 VARIANT* var1 )
1865 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1866 HRESULT hr = S_FALSE;
1867 IXMLDOMSchemaCollection *cur_schema = This->schema;
1869 TRACE("(%p)->(%p)\n", This, var1);
1871 VariantInit(var1); /* Test shows we don't call VariantClear here */
1872 V_VT(var1) = VT_NULL;
1874 if(cur_schema)
1876 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1877 if(SUCCEEDED(hr))
1878 V_VT(var1) = VT_DISPATCH;
1880 return hr;
1883 static HRESULT WINAPI domdoc_putref_schemas(
1884 IXMLDOMDocument2* iface,
1885 VARIANT var1)
1887 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1888 HRESULT hr = E_FAIL;
1889 IXMLDOMSchemaCollection *new_schema = NULL;
1891 FIXME("(%p): semi-stub\n", This);
1892 switch(V_VT(&var1))
1894 case VT_UNKNOWN:
1895 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1896 break;
1898 case VT_DISPATCH:
1899 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1900 break;
1902 case VT_NULL:
1903 case VT_EMPTY:
1904 hr = S_OK;
1905 break;
1907 default:
1908 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1911 if(SUCCEEDED(hr))
1913 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1914 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1917 return hr;
1920 static HRESULT WINAPI domdoc_validate(
1921 IXMLDOMDocument2* iface,
1922 IXMLDOMParseError** err)
1924 FIXME("\n");
1925 return E_NOTIMPL;
1928 static HRESULT WINAPI domdoc_setProperty(
1929 IXMLDOMDocument2* iface,
1930 BSTR p,
1931 VARIANT var)
1933 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1935 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1937 VARIANT varStr;
1938 HRESULT hr;
1939 BSTR bstr;
1941 V_VT(&varStr) = VT_EMPTY;
1942 if (V_VT(&var) != VT_BSTR)
1944 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1945 return hr;
1946 bstr = V_BSTR(&varStr);
1948 else
1949 bstr = V_BSTR(&var);
1951 hr = S_OK;
1952 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1953 This->bUseXPath = TRUE;
1954 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1955 This->bUseXPath = FALSE;
1956 else
1957 hr = E_FAIL;
1959 VariantClear(&varStr);
1960 return hr;
1963 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1964 return E_FAIL;
1967 static HRESULT WINAPI domdoc_getProperty(
1968 IXMLDOMDocument2* iface,
1969 BSTR p,
1970 VARIANT* var)
1972 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1974 if (var == NULL)
1975 return E_INVALIDARG;
1976 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1978 V_VT(var) = VT_BSTR;
1979 if (This->bUseXPath)
1980 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1981 else
1982 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1983 return S_OK;
1986 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1987 return E_FAIL;
1990 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1992 domdoc_QueryInterface,
1993 domdoc_AddRef,
1994 domdoc_Release,
1995 domdoc_GetTypeInfoCount,
1996 domdoc_GetTypeInfo,
1997 domdoc_GetIDsOfNames,
1998 domdoc_Invoke,
1999 domdoc_get_nodeName,
2000 domdoc_get_nodeValue,
2001 domdoc_put_nodeValue,
2002 domdoc_get_nodeType,
2003 domdoc_get_parentNode,
2004 domdoc_get_childNodes,
2005 domdoc_get_firstChild,
2006 domdoc_get_lastChild,
2007 domdoc_get_previousSibling,
2008 domdoc_get_nextSibling,
2009 domdoc_get_attributes,
2010 domdoc_insertBefore,
2011 domdoc_replaceChild,
2012 domdoc_removeChild,
2013 domdoc_appendChild,
2014 domdoc_hasChildNodes,
2015 domdoc_get_ownerDocument,
2016 domdoc_cloneNode,
2017 domdoc_get_nodeTypeString,
2018 domdoc_get_text,
2019 domdoc_put_text,
2020 domdoc_get_specified,
2021 domdoc_get_definition,
2022 domdoc_get_nodeTypedValue,
2023 domdoc_put_nodeTypedValue,
2024 domdoc_get_dataType,
2025 domdoc_put_dataType,
2026 domdoc_get_xml,
2027 domdoc_transformNode,
2028 domdoc_selectNodes,
2029 domdoc_selectSingleNode,
2030 domdoc_get_parsed,
2031 domdoc_get_namespaceURI,
2032 domdoc_get_prefix,
2033 domdoc_get_baseName,
2034 domdoc_transformNodeToObject,
2035 domdoc_get_doctype,
2036 domdoc_get_implementation,
2037 domdoc_get_documentElement,
2038 domdoc_put_documentElement,
2039 domdoc_createElement,
2040 domdoc_createDocumentFragment,
2041 domdoc_createTextNode,
2042 domdoc_createComment,
2043 domdoc_createCDATASection,
2044 domdoc_createProcessingInstruction,
2045 domdoc_createAttribute,
2046 domdoc_createEntityReference,
2047 domdoc_getElementsByTagName,
2048 domdoc_createNode,
2049 domdoc_nodeFromID,
2050 domdoc_load,
2051 domdoc_get_readyState,
2052 domdoc_get_parseError,
2053 domdoc_get_url,
2054 domdoc_get_async,
2055 domdoc_put_async,
2056 domdoc_abort,
2057 domdoc_loadXML,
2058 domdoc_save,
2059 domdoc_get_validateOnParse,
2060 domdoc_put_validateOnParse,
2061 domdoc_get_resolveExternals,
2062 domdoc_put_resolveExternals,
2063 domdoc_get_preserveWhiteSpace,
2064 domdoc_put_preserveWhiteSpace,
2065 domdoc_put_onReadyStateChange,
2066 domdoc_put_onDataAvailable,
2067 domdoc_put_onTransformNode,
2068 domdoc_get_namespaces,
2069 domdoc_get_schemas,
2070 domdoc_putref_schemas,
2071 domdoc_validate,
2072 domdoc_setProperty,
2073 domdoc_getProperty
2076 /* xmldoc implementation of IObjectWithSite */
2077 static HRESULT WINAPI
2078 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2080 domdoc *This = impl_from_IObjectWithSite(iface);
2081 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2084 static ULONG WINAPI
2085 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2087 domdoc *This = impl_from_IObjectWithSite(iface);
2088 return IXMLDocument_AddRef((IXMLDocument *)This);
2091 static ULONG WINAPI
2092 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2094 domdoc *This = impl_from_IObjectWithSite(iface);
2095 return IXMLDocument_Release((IXMLDocument *)This);
2098 static HRESULT WINAPI
2099 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2101 domdoc *This = impl_from_IObjectWithSite(iface);
2103 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2105 if ( !This->site )
2106 return E_FAIL;
2108 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2111 static HRESULT WINAPI
2112 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2114 domdoc *This = impl_from_IObjectWithSite(iface);
2116 TRACE("%p %p\n", iface, punk);
2118 if(!punk)
2120 if(This->site)
2122 IUnknown_Release( This->site );
2123 This->site = NULL;
2126 return S_OK;
2129 if ( punk )
2130 IUnknown_AddRef( punk );
2132 if(This->site)
2133 IUnknown_Release( This->site );
2135 This->site = punk;
2137 return S_OK;
2140 static const IObjectWithSiteVtbl domdocObjectSite =
2142 xmldoc_ObjectWithSite_QueryInterface,
2143 xmldoc_ObjectWithSite_AddRef,
2144 xmldoc_ObjectWithSite_Release,
2145 xmldoc_SetSite,
2146 xmldoc_GetSite,
2149 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2151 domdoc *This = impl_from_IObjectSafety(iface);
2152 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2155 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2157 domdoc *This = impl_from_IObjectSafety(iface);
2158 return IXMLDocument_AddRef((IXMLDocument *)This);
2161 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2163 domdoc *This = impl_from_IObjectSafety(iface);
2164 return IXMLDocument_Release((IXMLDocument *)This);
2167 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2169 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2170 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2172 domdoc *This = impl_from_IObjectSafety(iface);
2174 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2176 if(!pdwSupportedOptions || !pdwEnabledOptions)
2177 return E_POINTER;
2179 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2180 *pdwEnabledOptions = This->safeopt;
2182 return S_OK;
2185 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2186 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2188 domdoc *This = impl_from_IObjectSafety(iface);
2190 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2192 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2193 return E_FAIL;
2195 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2196 return S_OK;
2199 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2200 xmldoc_Safety_QueryInterface,
2201 xmldoc_Safety_AddRef,
2202 xmldoc_Safety_Release,
2203 xmldoc_Safety_GetInterfaceSafetyOptions,
2204 xmldoc_Safety_SetInterfaceSafetyOptions
2208 static const tid_t domdoc_iface_tids[] = {
2209 IXMLDOMNode_tid,
2210 IXMLDOMDocument_tid,
2211 IXMLDOMDocument2_tid,
2214 static dispex_static_data_t domdoc_dispex = {
2215 NULL,
2216 IXMLDOMDocument2_tid,
2217 NULL,
2218 domdoc_iface_tids
2221 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2223 domdoc *doc;
2225 doc = heap_alloc( sizeof (*doc) );
2226 if( !doc )
2227 return E_OUTOFMEMORY;
2229 doc->lpVtbl = &domdoc_vtbl;
2230 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2231 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2232 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2233 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2234 doc->ref = 1;
2235 doc->async = VARIANT_TRUE;
2236 doc->validating = 0;
2237 doc->resolving = 0;
2238 doc->preserving = 0;
2239 doc->bUseXPath = FALSE;
2240 doc->error = S_OK;
2241 doc->schema = NULL;
2242 doc->stream = NULL;
2243 doc->site = NULL;
2244 doc->safeopt = 0;
2245 doc->bsc = NULL;
2247 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2249 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2251 TRACE("returning iface %p\n", *document);
2252 return S_OK;
2255 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2257 xmlDocPtr xmldoc;
2258 HRESULT hr;
2260 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2262 xmldoc = xmlNewDoc(NULL);
2263 if(!xmldoc)
2264 return E_OUTOFMEMORY;
2266 xmldoc->_private = create_priv();
2268 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2269 if(FAILED(hr))
2270 xmlFreeDoc(xmldoc);
2272 return hr;
2275 IUnknown* create_domdoc( xmlNodePtr document )
2277 HRESULT hr;
2278 LPVOID pObj = NULL;
2280 TRACE("(%p)\n", document);
2282 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2283 if (FAILED(hr))
2284 return NULL;
2286 return pObj;
2289 #else
2291 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2293 MESSAGE("This program tried to use a DOMDocument object, but\n"
2294 "libxml2 support was not present at compile time.\n");
2295 return E_NOTIMPL;
2298 #endif