push 6e61d6ca5bcaf95ac09a664b4ba4f88238c927be
[wine/hacks.git] / dlls / msxml3 / domdoc.c
bloba29e9b2fb3e07b64d0aad331f4197c837ba3bac1
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): stub!\n", 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", This, 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", This, 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 domdoc *This = impl_from_IPersistStream(iface);
391 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
392 return E_NOTIMPL;
395 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
397 xmldoc_IPersistStream_QueryInterface,
398 xmldoc_IPersistStream_AddRef,
399 xmldoc_IPersistStream_Release,
400 xmldoc_IPersistStream_GetClassID,
401 xmldoc_IPersistStream_IsDirty,
402 xmldoc_IPersistStream_Load,
403 xmldoc_IPersistStream_Save,
404 xmldoc_IPersistStream_GetSizeMax,
407 /* ISupportErrorInfo interface */
408 static HRESULT WINAPI support_error_QueryInterface(
409 ISupportErrorInfo *iface,
410 REFIID riid, void** ppvObj )
412 domdoc *This = impl_from_ISupportErrorInfo(iface);
413 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
416 static ULONG WINAPI support_error_AddRef(
417 ISupportErrorInfo *iface )
419 domdoc *This = impl_from_ISupportErrorInfo(iface);
420 return IXMLDocument_AddRef((IXMLDocument *)This);
423 static ULONG WINAPI support_error_Release(
424 ISupportErrorInfo *iface )
426 domdoc *This = impl_from_ISupportErrorInfo(iface);
427 return IXMLDocument_Release((IXMLDocument *)This);
430 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
431 ISupportErrorInfo *iface,
432 REFIID riid )
434 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
435 return S_FALSE;
438 static const struct ISupportErrorInfoVtbl support_error_vtbl =
440 support_error_QueryInterface,
441 support_error_AddRef,
442 support_error_Release,
443 support_error_InterfaceSupportsErrorInfo
446 /* IXMLDOMDocument2 interface */
447 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
449 domdoc *This = impl_from_IXMLDOMDocument2( iface );
451 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
453 *ppvObject = NULL;
455 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
456 IsEqualGUID( riid, &IID_IDispatch ) ||
457 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
458 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
460 *ppvObject = iface;
462 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
464 *ppvObject = IXMLDOMNode_from_impl(&This->node);
466 else if (IsEqualGUID(&IID_IPersistStream, riid))
468 *ppvObject = &(This->lpvtblIPersistStream);
470 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
472 *ppvObject = &(This->lpvtblIObjectWithSite);
474 else if (IsEqualGUID(&IID_IObjectSafety, riid))
476 *ppvObject = &(This->lpvtblIObjectSafety);
478 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
480 *ppvObject = &This->lpvtblISupportErrorInfo;
482 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
484 return *ppvObject ? S_OK : E_NOINTERFACE;
486 else if(IsEqualGUID(&IID_IRunnableObject, riid))
488 TRACE("IID_IRunnableObject not supported returning NULL\n");
489 return E_NOINTERFACE;
491 else
493 FIXME("interface %s not implemented\n", debugstr_guid(riid));
494 return E_NOINTERFACE;
497 IUnknown_AddRef((IUnknown*)*ppvObject);
499 return S_OK;
503 static ULONG WINAPI domdoc_AddRef(
504 IXMLDOMDocument2 *iface )
506 domdoc *This = impl_from_IXMLDOMDocument2( iface );
507 TRACE("%p\n", This );
508 return InterlockedIncrement( &This->ref );
512 static ULONG WINAPI domdoc_Release(
513 IXMLDOMDocument2 *iface )
515 domdoc *This = impl_from_IXMLDOMDocument2( iface );
516 LONG ref;
518 TRACE("%p\n", This );
520 ref = InterlockedDecrement( &This->ref );
521 if ( ref == 0 )
523 if(This->bsc)
524 detach_bsc(This->bsc);
526 if (This->site)
527 IUnknown_Release( This->site );
528 destroy_xmlnode(&This->node);
529 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
530 if (This->stream) IStream_Release(This->stream);
531 HeapFree( GetProcessHeap(), 0, This );
534 return ref;
537 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
539 domdoc *This = impl_from_IXMLDOMDocument2( iface );
541 TRACE("(%p)->(%p)\n", This, pctinfo);
543 *pctinfo = 1;
545 return S_OK;
548 static HRESULT WINAPI domdoc_GetTypeInfo(
549 IXMLDOMDocument2 *iface,
550 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
552 domdoc *This = impl_from_IXMLDOMDocument2( iface );
553 HRESULT hr;
555 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
557 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
559 return hr;
562 static HRESULT WINAPI domdoc_GetIDsOfNames(
563 IXMLDOMDocument2 *iface,
564 REFIID riid,
565 LPOLESTR* rgszNames,
566 UINT cNames,
567 LCID lcid,
568 DISPID* rgDispId)
570 domdoc *This = impl_from_IXMLDOMDocument2( iface );
571 ITypeInfo *typeinfo;
572 HRESULT hr;
574 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
575 lcid, rgDispId);
577 if(!rgszNames || cNames == 0 || !rgDispId)
578 return E_INVALIDARG;
580 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
581 if(SUCCEEDED(hr))
583 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
584 ITypeInfo_Release(typeinfo);
587 return hr;
591 static HRESULT WINAPI domdoc_Invoke(
592 IXMLDOMDocument2 *iface,
593 DISPID dispIdMember,
594 REFIID riid,
595 LCID lcid,
596 WORD wFlags,
597 DISPPARAMS* pDispParams,
598 VARIANT* pVarResult,
599 EXCEPINFO* pExcepInfo,
600 UINT* puArgErr)
602 domdoc *This = impl_from_IXMLDOMDocument2( iface );
603 ITypeInfo *typeinfo;
604 HRESULT hr;
606 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
607 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
609 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
610 if(SUCCEEDED(hr))
612 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
613 pVarResult, pExcepInfo, puArgErr);
614 ITypeInfo_Release(typeinfo);
617 return hr;
621 static HRESULT WINAPI domdoc_get_nodeName(
622 IXMLDOMDocument2 *iface,
623 BSTR* name )
625 domdoc *This = impl_from_IXMLDOMDocument2( iface );
626 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
630 static HRESULT WINAPI domdoc_get_nodeValue(
631 IXMLDOMDocument2 *iface,
632 VARIANT* value )
634 domdoc *This = impl_from_IXMLDOMDocument2( iface );
635 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
639 static HRESULT WINAPI domdoc_put_nodeValue(
640 IXMLDOMDocument2 *iface,
641 VARIANT value)
643 domdoc *This = impl_from_IXMLDOMDocument2( iface );
644 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
648 static HRESULT WINAPI domdoc_get_nodeType(
649 IXMLDOMDocument2 *iface,
650 DOMNodeType* type )
652 domdoc *This = impl_from_IXMLDOMDocument2( iface );
653 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
657 static HRESULT WINAPI domdoc_get_parentNode(
658 IXMLDOMDocument2 *iface,
659 IXMLDOMNode** parent )
661 domdoc *This = impl_from_IXMLDOMDocument2( iface );
662 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
666 static HRESULT WINAPI domdoc_get_childNodes(
667 IXMLDOMDocument2 *iface,
668 IXMLDOMNodeList** childList )
670 domdoc *This = impl_from_IXMLDOMDocument2( iface );
671 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
675 static HRESULT WINAPI domdoc_get_firstChild(
676 IXMLDOMDocument2 *iface,
677 IXMLDOMNode** firstChild )
679 domdoc *This = impl_from_IXMLDOMDocument2( iface );
680 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
684 static HRESULT WINAPI domdoc_get_lastChild(
685 IXMLDOMDocument2 *iface,
686 IXMLDOMNode** lastChild )
688 domdoc *This = impl_from_IXMLDOMDocument2( iface );
689 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
693 static HRESULT WINAPI domdoc_get_previousSibling(
694 IXMLDOMDocument2 *iface,
695 IXMLDOMNode** previousSibling )
697 domdoc *This = impl_from_IXMLDOMDocument2( iface );
698 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
702 static HRESULT WINAPI domdoc_get_nextSibling(
703 IXMLDOMDocument2 *iface,
704 IXMLDOMNode** nextSibling )
706 domdoc *This = impl_from_IXMLDOMDocument2( iface );
707 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
711 static HRESULT WINAPI domdoc_get_attributes(
712 IXMLDOMDocument2 *iface,
713 IXMLDOMNamedNodeMap** attributeMap )
715 domdoc *This = impl_from_IXMLDOMDocument2( iface );
716 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
720 static HRESULT WINAPI domdoc_insertBefore(
721 IXMLDOMDocument2 *iface,
722 IXMLDOMNode* newChild,
723 VARIANT refChild,
724 IXMLDOMNode** outNewChild )
726 domdoc *This = impl_from_IXMLDOMDocument2( iface );
727 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
731 static HRESULT WINAPI domdoc_replaceChild(
732 IXMLDOMDocument2 *iface,
733 IXMLDOMNode* newChild,
734 IXMLDOMNode* oldChild,
735 IXMLDOMNode** outOldChild)
737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
738 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
742 static HRESULT WINAPI domdoc_removeChild(
743 IXMLDOMDocument2 *iface,
744 IXMLDOMNode* childNode,
745 IXMLDOMNode** oldChild)
747 domdoc *This = impl_from_IXMLDOMDocument2( iface );
748 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
752 static HRESULT WINAPI domdoc_appendChild(
753 IXMLDOMDocument2 *iface,
754 IXMLDOMNode* newChild,
755 IXMLDOMNode** outNewChild)
757 domdoc *This = impl_from_IXMLDOMDocument2( iface );
758 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
762 static HRESULT WINAPI domdoc_hasChildNodes(
763 IXMLDOMDocument2 *iface,
764 VARIANT_BOOL* hasChild)
766 domdoc *This = impl_from_IXMLDOMDocument2( iface );
767 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
771 static HRESULT WINAPI domdoc_get_ownerDocument(
772 IXMLDOMDocument2 *iface,
773 IXMLDOMDocument** DOMDocument)
775 domdoc *This = impl_from_IXMLDOMDocument2( iface );
776 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
780 static HRESULT WINAPI domdoc_cloneNode(
781 IXMLDOMDocument2 *iface,
782 VARIANT_BOOL deep,
783 IXMLDOMNode** cloneRoot)
785 domdoc *This = impl_from_IXMLDOMDocument2( iface );
786 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
790 static HRESULT WINAPI domdoc_get_nodeTypeString(
791 IXMLDOMDocument2 *iface,
792 BSTR* nodeType )
794 domdoc *This = impl_from_IXMLDOMDocument2( iface );
795 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
799 static HRESULT WINAPI domdoc_get_text(
800 IXMLDOMDocument2 *iface,
801 BSTR* text )
803 domdoc *This = impl_from_IXMLDOMDocument2( iface );
804 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
808 static HRESULT WINAPI domdoc_put_text(
809 IXMLDOMDocument2 *iface,
810 BSTR text )
812 domdoc *This = impl_from_IXMLDOMDocument2( iface );
813 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
817 static HRESULT WINAPI domdoc_get_specified(
818 IXMLDOMDocument2 *iface,
819 VARIANT_BOOL* isSpecified )
821 domdoc *This = impl_from_IXMLDOMDocument2( iface );
822 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
826 static HRESULT WINAPI domdoc_get_definition(
827 IXMLDOMDocument2 *iface,
828 IXMLDOMNode** definitionNode )
830 domdoc *This = impl_from_IXMLDOMDocument2( iface );
831 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
835 static HRESULT WINAPI domdoc_get_nodeTypedValue(
836 IXMLDOMDocument2 *iface,
837 VARIANT* typedValue )
839 domdoc *This = impl_from_IXMLDOMDocument2( iface );
840 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
843 static HRESULT WINAPI domdoc_put_nodeTypedValue(
844 IXMLDOMDocument2 *iface,
845 VARIANT typedValue )
847 domdoc *This = impl_from_IXMLDOMDocument2( iface );
848 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
852 static HRESULT WINAPI domdoc_get_dataType(
853 IXMLDOMDocument2 *iface,
854 VARIANT* dataTypeName )
856 domdoc *This = impl_from_IXMLDOMDocument2( iface );
857 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
861 static HRESULT WINAPI domdoc_put_dataType(
862 IXMLDOMDocument2 *iface,
863 BSTR dataTypeName )
865 domdoc *This = impl_from_IXMLDOMDocument2( iface );
866 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
870 static HRESULT WINAPI domdoc_get_xml(
871 IXMLDOMDocument2 *iface,
872 BSTR* xmlString )
874 domdoc *This = impl_from_IXMLDOMDocument2( iface );
875 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
879 static HRESULT WINAPI domdoc_transformNode(
880 IXMLDOMDocument2 *iface,
881 IXMLDOMNode* styleSheet,
882 BSTR* xmlString )
884 domdoc *This = impl_from_IXMLDOMDocument2( iface );
885 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
889 static HRESULT WINAPI domdoc_selectNodes(
890 IXMLDOMDocument2 *iface,
891 BSTR queryString,
892 IXMLDOMNodeList** resultList )
894 domdoc *This = impl_from_IXMLDOMDocument2( iface );
895 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
899 static HRESULT WINAPI domdoc_selectSingleNode(
900 IXMLDOMDocument2 *iface,
901 BSTR queryString,
902 IXMLDOMNode** resultNode )
904 domdoc *This = impl_from_IXMLDOMDocument2( iface );
905 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
909 static HRESULT WINAPI domdoc_get_parsed(
910 IXMLDOMDocument2 *iface,
911 VARIANT_BOOL* isParsed )
913 domdoc *This = impl_from_IXMLDOMDocument2( iface );
914 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
918 static HRESULT WINAPI domdoc_get_namespaceURI(
919 IXMLDOMDocument2 *iface,
920 BSTR* namespaceURI )
922 domdoc *This = impl_from_IXMLDOMDocument2( iface );
923 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
927 static HRESULT WINAPI domdoc_get_prefix(
928 IXMLDOMDocument2 *iface,
929 BSTR* prefixString )
931 domdoc *This = impl_from_IXMLDOMDocument2( iface );
932 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
936 static HRESULT WINAPI domdoc_get_baseName(
937 IXMLDOMDocument2 *iface,
938 BSTR* nameString )
940 domdoc *This = impl_from_IXMLDOMDocument2( iface );
941 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
945 static HRESULT WINAPI domdoc_transformNodeToObject(
946 IXMLDOMDocument2 *iface,
947 IXMLDOMNode* stylesheet,
948 VARIANT outputObject)
950 domdoc *This = impl_from_IXMLDOMDocument2( iface );
951 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
955 static HRESULT WINAPI domdoc_get_doctype(
956 IXMLDOMDocument2 *iface,
957 IXMLDOMDocumentType** documentType )
959 domdoc *This = impl_from_IXMLDOMDocument2(iface);
960 FIXME("(%p)\n", This);
961 return E_NOTIMPL;
965 static HRESULT WINAPI domdoc_get_implementation(
966 IXMLDOMDocument2 *iface,
967 IXMLDOMImplementation** impl )
969 domdoc *This = impl_from_IXMLDOMDocument2(iface);
971 TRACE("(%p)->(%p)\n", This, impl);
973 if(!impl)
974 return E_INVALIDARG;
976 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
978 return S_OK;
981 static HRESULT WINAPI domdoc_get_documentElement(
982 IXMLDOMDocument2 *iface,
983 IXMLDOMElement** DOMElement )
985 domdoc *This = impl_from_IXMLDOMDocument2( iface );
986 xmlDocPtr xmldoc = NULL;
987 xmlNodePtr root = NULL;
988 IXMLDOMNode *element_node;
989 HRESULT hr;
991 TRACE("(%p)->(%p)\n", This, DOMElement);
993 if(!DOMElement)
994 return E_INVALIDARG;
996 *DOMElement = NULL;
998 xmldoc = get_doc( This );
1000 root = xmlDocGetRootElement( xmldoc );
1001 if ( !root )
1002 return S_FALSE;
1004 element_node = create_node( root );
1005 if(!element_node) return S_FALSE;
1007 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
1008 IXMLDOMNode_Release(element_node);
1010 return hr;
1014 static HRESULT WINAPI domdoc_put_documentElement(
1015 IXMLDOMDocument2 *iface,
1016 IXMLDOMElement* DOMElement )
1018 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1019 IXMLDOMNode *elementNode;
1020 xmlNodePtr oldRoot;
1021 xmlnode *xmlNode;
1022 HRESULT hr;
1024 TRACE("(%p)->(%p)\n", This, DOMElement);
1026 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1027 if(FAILED(hr))
1028 return hr;
1030 xmlNode = impl_from_IXMLDOMNode( elementNode );
1032 if(!xmlNode->node->parent)
1033 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1034 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1036 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1037 IXMLDOMNode_Release( elementNode );
1039 if(oldRoot)
1040 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1042 return S_OK;
1046 static HRESULT WINAPI domdoc_createElement(
1047 IXMLDOMDocument2 *iface,
1048 BSTR tagname,
1049 IXMLDOMElement** element )
1051 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1052 IXMLDOMNode *node;
1053 VARIANT type;
1054 HRESULT hr;
1056 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1058 if (!element || !tagname) return E_INVALIDARG;
1060 V_VT(&type) = VT_I1;
1061 V_I1(&type) = NODE_ELEMENT;
1063 hr = IXMLDOMDocument_createNode(iface, type, tagname, NULL, &node);
1064 if (hr == S_OK)
1066 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1067 IXMLDOMNode_Release(node);
1070 return hr;
1074 static HRESULT WINAPI domdoc_createDocumentFragment(
1075 IXMLDOMDocument2 *iface,
1076 IXMLDOMDocumentFragment** frag )
1078 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1079 IXMLDOMNode *node;
1080 VARIANT type;
1081 HRESULT hr;
1083 TRACE("(%p)->(%p)\n", This, frag);
1085 if (!frag) return E_INVALIDARG;
1087 *frag = NULL;
1089 V_VT(&type) = VT_I1;
1090 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1092 hr = IXMLDOMDocument_createNode(iface, type, NULL, NULL, &node);
1093 if (hr == S_OK)
1095 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1096 IXMLDOMNode_Release(node);
1099 return hr;
1103 static HRESULT WINAPI domdoc_createTextNode(
1104 IXMLDOMDocument2 *iface,
1105 BSTR data,
1106 IXMLDOMText** text )
1108 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1109 IXMLDOMNode *node;
1110 VARIANT type;
1111 HRESULT hr;
1113 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1115 if (!text) return E_INVALIDARG;
1117 *text = NULL;
1119 V_VT(&type) = VT_I1;
1120 V_I1(&type) = NODE_TEXT;
1122 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1123 if (hr == S_OK)
1125 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1126 IXMLDOMNode_Release(node);
1127 hr = IXMLDOMText_put_data(*text, data);
1130 return hr;
1134 static HRESULT WINAPI domdoc_createComment(
1135 IXMLDOMDocument2 *iface,
1136 BSTR data,
1137 IXMLDOMComment** comment )
1139 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1140 VARIANT type;
1141 HRESULT hr;
1142 IXMLDOMNode *node;
1144 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1146 if (!comment) return E_INVALIDARG;
1148 *comment = NULL;
1150 V_VT(&type) = VT_I1;
1151 V_I1(&type) = NODE_COMMENT;
1153 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1154 if (hr == S_OK)
1156 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1157 IXMLDOMNode_Release(node);
1158 hr = IXMLDOMComment_put_data(*comment, data);
1161 return hr;
1165 static HRESULT WINAPI domdoc_createCDATASection(
1166 IXMLDOMDocument2 *iface,
1167 BSTR data,
1168 IXMLDOMCDATASection** cdata )
1170 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1171 IXMLDOMNode *node;
1172 VARIANT type;
1173 HRESULT hr;
1175 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1177 if (!cdata) return E_INVALIDARG;
1179 *cdata = NULL;
1181 V_VT(&type) = VT_I1;
1182 V_I1(&type) = NODE_CDATA_SECTION;
1184 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1185 if (hr == S_OK)
1187 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1188 IXMLDOMNode_Release(node);
1189 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1192 return hr;
1196 static HRESULT WINAPI domdoc_createProcessingInstruction(
1197 IXMLDOMDocument2 *iface,
1198 BSTR target,
1199 BSTR data,
1200 IXMLDOMProcessingInstruction** pi )
1202 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1203 IXMLDOMNode *node;
1204 VARIANT type;
1205 HRESULT hr;
1207 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1209 if (!pi) return E_INVALIDARG;
1211 *pi = NULL;
1213 V_VT(&type) = VT_I1;
1214 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1216 hr = IXMLDOMDocument2_createNode(iface, type, target, NULL, &node);
1217 if (hr == S_OK)
1219 VARIANT v_data;
1221 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1222 V_VT(&v_data) = VT_BSTR;
1223 V_BSTR(&v_data) = data;
1225 hr = IXMLDOMNode_put_nodeValue( node, v_data );
1227 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1228 IXMLDOMNode_Release(node);
1231 return hr;
1235 static HRESULT WINAPI domdoc_createAttribute(
1236 IXMLDOMDocument2 *iface,
1237 BSTR name,
1238 IXMLDOMAttribute** attribute )
1240 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1241 IXMLDOMNode *node;
1242 VARIANT type;
1243 HRESULT hr;
1245 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1247 if (!attribute || !name) return E_INVALIDARG;
1249 V_VT(&type) = VT_I1;
1250 V_I1(&type) = NODE_ATTRIBUTE;
1252 hr = IXMLDOMDocument_createNode(iface, type, name, NULL, &node);
1253 if (hr == S_OK)
1255 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1256 IXMLDOMNode_Release(node);
1259 return hr;
1263 static HRESULT WINAPI domdoc_createEntityReference(
1264 IXMLDOMDocument2 *iface,
1265 BSTR name,
1266 IXMLDOMEntityReference** entityref )
1268 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1269 IXMLDOMNode *node;
1270 VARIANT type;
1271 HRESULT hr;
1273 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1275 if (!entityref) return E_INVALIDARG;
1277 *entityref = NULL;
1279 V_VT(&type) = VT_I1;
1280 V_I1(&type) = NODE_ENTITY_REFERENCE;
1282 hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
1283 if (hr == S_OK)
1285 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1286 IXMLDOMNode_Release(node);
1289 return hr;
1293 static HRESULT WINAPI domdoc_getElementsByTagName(
1294 IXMLDOMDocument2 *iface,
1295 BSTR tagName,
1296 IXMLDOMNodeList** resultList )
1298 static const WCHAR xpathformat[] =
1299 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1300 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1301 LPWSTR szPattern;
1302 HRESULT hr;
1303 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1305 if (tagName[0] == '*' && tagName[1] == 0)
1307 szPattern = heap_alloc(sizeof(WCHAR)*4);
1308 szPattern[0] = szPattern[1] = '/';
1309 szPattern[2] = '*';
1310 szPattern[3] = 0;
1312 else
1314 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1315 wsprintfW(szPattern, xpathformat, tagName);
1318 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1319 heap_free(szPattern);
1321 return hr;
1324 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1326 VARIANT tmp;
1327 HRESULT hr;
1329 VariantInit(&tmp);
1330 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1331 if(FAILED(hr))
1332 return E_INVALIDARG;
1334 *type = V_I4(&tmp);
1336 return S_OK;
1339 static HRESULT WINAPI domdoc_createNode(
1340 IXMLDOMDocument2 *iface,
1341 VARIANT Type,
1342 BSTR name,
1343 BSTR namespaceURI,
1344 IXMLDOMNode** node )
1346 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1347 DOMNodeType node_type;
1348 xmlNodePtr xmlnode;
1349 xmlChar *xml_name;
1350 HRESULT hr;
1352 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1354 if(!node) return E_INVALIDARG;
1356 if(namespaceURI && namespaceURI[0])
1357 FIXME("nodes with namespaces currently not supported.\n");
1359 hr = get_node_type(Type, &node_type);
1360 if(FAILED(hr)) return hr;
1362 TRACE("node_type %d\n", node_type);
1364 /* exit earlier for types that need name */
1365 switch(node_type)
1367 case NODE_ELEMENT:
1368 case NODE_ATTRIBUTE:
1369 case NODE_ENTITY_REFERENCE:
1370 case NODE_PROCESSING_INSTRUCTION:
1371 if (!name || SysStringLen(name) == 0) return E_FAIL;
1372 default:
1373 break;
1376 xml_name = xmlChar_from_wchar(name);
1378 switch(node_type)
1380 case NODE_ELEMENT:
1381 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1382 break;
1383 case NODE_ATTRIBUTE:
1384 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1385 break;
1386 case NODE_TEXT:
1387 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1388 break;
1389 case NODE_CDATA_SECTION:
1390 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1391 break;
1392 case NODE_ENTITY_REFERENCE:
1393 xmlnode = xmlNewReference(get_doc(This), xml_name);
1394 break;
1395 case NODE_PROCESSING_INSTRUCTION:
1396 #ifdef HAVE_XMLNEWDOCPI
1397 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1398 #else
1399 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1400 xmlnode = NULL;
1401 #endif
1402 break;
1403 case NODE_COMMENT:
1404 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1405 break;
1406 case NODE_DOCUMENT_FRAGMENT:
1407 xmlnode = xmlNewDocFragment(get_doc(This));
1408 break;
1409 /* unsupported types */
1410 case NODE_DOCUMENT:
1411 case NODE_DOCUMENT_TYPE:
1412 case NODE_ENTITY:
1413 case NODE_NOTATION:
1414 heap_free(xml_name);
1415 return E_INVALIDARG;
1416 default:
1417 FIXME("unhandled node type %d\n", node_type);
1418 xmlnode = NULL;
1419 break;
1422 *node = create_node(xmlnode);
1423 heap_free(xml_name);
1425 if(*node)
1427 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1428 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1429 return S_OK;
1432 return E_FAIL;
1435 static HRESULT WINAPI domdoc_nodeFromID(
1436 IXMLDOMDocument2 *iface,
1437 BSTR idString,
1438 IXMLDOMNode** node )
1440 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1441 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1442 return E_NOTIMPL;
1445 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1447 domdoc *This = obj;
1448 xmlDocPtr xmldoc;
1450 xmldoc = doparse( ptr, len );
1451 if(xmldoc) {
1452 xmldoc->_private = create_priv();
1453 return attach_xmldoc(&This->node, xmldoc);
1456 return S_OK;
1459 static HRESULT doread( domdoc *This, LPWSTR filename )
1461 bsc_t *bsc;
1462 HRESULT hr;
1464 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1465 if(FAILED(hr))
1466 return hr;
1468 if(This->bsc)
1469 detach_bsc(This->bsc);
1471 This->bsc = bsc;
1472 return S_OK;
1475 static HRESULT WINAPI domdoc_load(
1476 IXMLDOMDocument2 *iface,
1477 VARIANT xmlSource,
1478 VARIANT_BOOL* isSuccessful )
1480 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1481 LPWSTR filename = NULL;
1482 HRESULT hr = S_FALSE;
1483 IXMLDOMDocument2 *pNewDoc = NULL;
1484 IStream *pStream = NULL;
1485 xmlDocPtr xmldoc;
1487 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1489 *isSuccessful = VARIANT_FALSE;
1491 assert( &This->node );
1493 switch( V_VT(&xmlSource) )
1495 case VT_BSTR:
1496 filename = V_BSTR(&xmlSource);
1497 break;
1498 case VT_UNKNOWN:
1499 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1500 if(hr == S_OK)
1502 if(pNewDoc)
1504 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1505 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1506 hr = attach_xmldoc(&This->node, xmldoc);
1508 if(SUCCEEDED(hr))
1509 *isSuccessful = VARIANT_TRUE;
1511 return hr;
1514 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1515 if(hr == S_OK)
1517 IPersistStream *pDocStream;
1518 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1519 if(hr == S_OK)
1521 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1522 IStream_Release(pStream);
1523 if(hr == S_OK)
1525 *isSuccessful = VARIANT_TRUE;
1527 TRACE("Using ID_IStream to load Document\n");
1528 return S_OK;
1530 else
1532 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1535 else
1537 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1540 else
1542 /* ISequentialStream */
1543 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1545 break;
1546 default:
1547 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1550 TRACE("filename (%s)\n", debugstr_w(filename));
1552 if ( filename )
1554 hr = doread( This, filename );
1556 if ( FAILED(hr) )
1557 This->error = E_FAIL;
1558 else
1560 hr = This->error = S_OK;
1561 *isSuccessful = VARIANT_TRUE;
1565 if(!filename || FAILED(hr)) {
1566 xmldoc = xmlNewDoc(NULL);
1567 xmldoc->_private = create_priv();
1568 hr = attach_xmldoc(&This->node, xmldoc);
1569 if(SUCCEEDED(hr))
1570 hr = S_FALSE;
1573 TRACE("ret (%d)\n", hr);
1575 return hr;
1579 static HRESULT WINAPI domdoc_get_readyState(
1580 IXMLDOMDocument2 *iface,
1581 LONG *value )
1583 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1584 FIXME("(%p)->(%p)\n", This, value);
1585 return E_NOTIMPL;
1589 static HRESULT WINAPI domdoc_get_parseError(
1590 IXMLDOMDocument2 *iface,
1591 IXMLDOMParseError** errorObj )
1593 BSTR error_string = NULL;
1594 static const WCHAR err[] = {'e','r','r','o','r',0};
1595 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1597 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1599 if(This->error)
1600 error_string = SysAllocString(err);
1602 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1603 if(!*errorObj) return E_OUTOFMEMORY;
1604 return S_OK;
1608 static HRESULT WINAPI domdoc_get_url(
1609 IXMLDOMDocument2 *iface,
1610 BSTR* urlString )
1612 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1613 FIXME("(%p)->(%p)\n", This, urlString);
1614 return E_NOTIMPL;
1618 static HRESULT WINAPI domdoc_get_async(
1619 IXMLDOMDocument2 *iface,
1620 VARIANT_BOOL* isAsync )
1622 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1624 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1625 *isAsync = This->async;
1626 return S_OK;
1630 static HRESULT WINAPI domdoc_put_async(
1631 IXMLDOMDocument2 *iface,
1632 VARIANT_BOOL isAsync )
1634 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1636 TRACE("(%p)->(%d)\n", This, isAsync);
1637 This->async = isAsync;
1638 return S_OK;
1642 static HRESULT WINAPI domdoc_abort(
1643 IXMLDOMDocument2 *iface )
1645 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1646 FIXME("%p\n", This);
1647 return E_NOTIMPL;
1651 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1653 UINT len, blen = SysStringLen( bstr );
1654 LPSTR str;
1656 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1657 str = heap_alloc( len );
1658 if ( !str )
1659 return FALSE;
1660 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1661 *plen = len;
1662 *pstr = str;
1663 return TRUE;
1666 static HRESULT WINAPI domdoc_loadXML(
1667 IXMLDOMDocument2 *iface,
1668 BSTR bstrXML,
1669 VARIANT_BOOL* isSuccessful )
1671 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1672 xmlDocPtr xmldoc = NULL;
1673 char *str;
1674 int len;
1675 HRESULT hr = S_FALSE, hr2;
1677 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
1679 assert ( &This->node );
1681 if ( isSuccessful )
1683 *isSuccessful = VARIANT_FALSE;
1685 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1687 xmldoc = doparse( str, len );
1688 heap_free( str );
1689 if ( !xmldoc )
1690 This->error = E_FAIL;
1691 else
1693 hr = This->error = S_OK;
1694 *isSuccessful = VARIANT_TRUE;
1698 if(!xmldoc)
1699 xmldoc = xmlNewDoc(NULL);
1701 xmldoc->_private = create_priv();
1702 hr2 = attach_xmldoc( &This->node, xmldoc );
1703 if( FAILED(hr2) )
1704 hr = hr2;
1706 return hr;
1709 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1710 int len)
1712 DWORD written = -1;
1714 if(!WriteFile(ctx, buffer, len, &written, NULL))
1716 WARN("write error\n");
1717 return -1;
1719 else
1720 return written;
1723 static int XMLCALL domdoc_save_closecallback(void *ctx)
1725 return CloseHandle(ctx) ? 0 : -1;
1728 static HRESULT WINAPI domdoc_save(
1729 IXMLDOMDocument2 *iface,
1730 VARIANT destination )
1732 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1733 HANDLE handle;
1734 xmlSaveCtxtPtr ctx;
1735 HRESULT ret = S_OK;
1737 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1738 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1740 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1742 FIXME("Unhandled vt %d\n", V_VT(&destination));
1743 return S_FALSE;
1746 if(V_VT(&destination) == VT_UNKNOWN)
1748 IUnknown *pUnk = V_UNKNOWN(&destination);
1749 IXMLDOMDocument *pDocument;
1751 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1752 if(ret == S_OK)
1754 BSTR bXML;
1755 VARIANT_BOOL bSuccessful;
1757 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1758 if(ret == S_OK)
1760 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1762 SysFreeString(bXML);
1765 IXMLDOMDocument_Release(pDocument);
1768 TRACE("ret %d\n", ret);
1770 return ret;
1773 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1774 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1775 if( handle == INVALID_HANDLE_VALUE )
1777 WARN("failed to create file\n");
1778 return S_FALSE;
1781 /* disable top XML declaration */
1782 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1783 handle, NULL, XML_SAVE_NO_DECL);
1784 if (!ctx)
1786 CloseHandle(handle);
1787 return S_FALSE;
1790 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1791 /* will close file through close callback */
1792 xmlSaveClose(ctx);
1794 return ret;
1797 static HRESULT WINAPI domdoc_get_validateOnParse(
1798 IXMLDOMDocument2 *iface,
1799 VARIANT_BOOL* isValidating )
1801 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1803 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
1804 *isValidating = This->validating;
1805 return S_OK;
1809 static HRESULT WINAPI domdoc_put_validateOnParse(
1810 IXMLDOMDocument2 *iface,
1811 VARIANT_BOOL isValidating )
1813 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1815 TRACE("(%p)->(%d)\n", This, isValidating);
1816 This->validating = isValidating;
1817 return S_OK;
1821 static HRESULT WINAPI domdoc_get_resolveExternals(
1822 IXMLDOMDocument2 *iface,
1823 VARIANT_BOOL* isResolving )
1825 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1827 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
1828 *isResolving = This->resolving;
1829 return S_OK;
1833 static HRESULT WINAPI domdoc_put_resolveExternals(
1834 IXMLDOMDocument2 *iface,
1835 VARIANT_BOOL isResolving )
1837 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1839 TRACE("(%p)->(%d)\n", This, isResolving);
1840 This->resolving = isResolving;
1841 return S_OK;
1845 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1846 IXMLDOMDocument2 *iface,
1847 VARIANT_BOOL* isPreserving )
1849 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1851 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
1852 *isPreserving = This->preserving;
1853 return S_OK;
1857 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1858 IXMLDOMDocument2 *iface,
1859 VARIANT_BOOL isPreserving )
1861 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1863 TRACE("(%p)->(%d)\n", This, isPreserving);
1864 This->preserving = isPreserving;
1865 return S_OK;
1869 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1870 IXMLDOMDocument2 *iface,
1871 VARIANT readyStateChangeSink )
1873 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1874 FIXME("%p\n", This);
1875 return E_NOTIMPL;
1879 static HRESULT WINAPI domdoc_put_onDataAvailable(
1880 IXMLDOMDocument2 *iface,
1881 VARIANT onDataAvailableSink )
1883 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1884 FIXME("%p\n", This);
1885 return E_NOTIMPL;
1888 static HRESULT WINAPI domdoc_put_onTransformNode(
1889 IXMLDOMDocument2 *iface,
1890 VARIANT onTransformNodeSink )
1892 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1893 FIXME("%p\n", This);
1894 return E_NOTIMPL;
1897 static HRESULT WINAPI domdoc_get_namespaces(
1898 IXMLDOMDocument2* iface,
1899 IXMLDOMSchemaCollection** schemaCollection )
1901 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1902 FIXME("(%p)->(%p)\n", This, schemaCollection);
1903 return E_NOTIMPL;
1906 static HRESULT WINAPI domdoc_get_schemas(
1907 IXMLDOMDocument2* iface,
1908 VARIANT* var1 )
1910 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1911 HRESULT hr = S_FALSE;
1912 IXMLDOMSchemaCollection *cur_schema = This->schema;
1914 TRACE("(%p)->(%p)\n", This, var1);
1916 VariantInit(var1); /* Test shows we don't call VariantClear here */
1917 V_VT(var1) = VT_NULL;
1919 if(cur_schema)
1921 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1922 if(SUCCEEDED(hr))
1923 V_VT(var1) = VT_DISPATCH;
1925 return hr;
1928 static HRESULT WINAPI domdoc_putref_schemas(
1929 IXMLDOMDocument2* iface,
1930 VARIANT var1)
1932 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1933 HRESULT hr = E_FAIL;
1934 IXMLDOMSchemaCollection *new_schema = NULL;
1936 FIXME("(%p): semi-stub\n", This);
1937 switch(V_VT(&var1))
1939 case VT_UNKNOWN:
1940 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1941 break;
1943 case VT_DISPATCH:
1944 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1945 break;
1947 case VT_NULL:
1948 case VT_EMPTY:
1949 hr = S_OK;
1950 break;
1952 default:
1953 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1956 if(SUCCEEDED(hr))
1958 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1959 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1962 return hr;
1965 static HRESULT WINAPI domdoc_validate(
1966 IXMLDOMDocument2* iface,
1967 IXMLDOMParseError** err)
1969 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1970 FIXME("(%p)->(%p)\n", This, err);
1971 return E_NOTIMPL;
1974 static HRESULT WINAPI domdoc_setProperty(
1975 IXMLDOMDocument2* iface,
1976 BSTR p,
1977 VARIANT var)
1979 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1981 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
1983 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1985 VARIANT varStr;
1986 HRESULT hr;
1987 BSTR bstr;
1989 V_VT(&varStr) = VT_EMPTY;
1990 if (V_VT(&var) != VT_BSTR)
1992 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1993 return hr;
1994 bstr = V_BSTR(&varStr);
1996 else
1997 bstr = V_BSTR(&var);
1999 hr = S_OK;
2000 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
2001 This->bUseXPath = TRUE;
2002 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
2003 This->bUseXPath = FALSE;
2004 else
2005 hr = E_FAIL;
2007 VariantClear(&varStr);
2008 return hr;
2011 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2012 return E_FAIL;
2015 static HRESULT WINAPI domdoc_getProperty(
2016 IXMLDOMDocument2* iface,
2017 BSTR p,
2018 VARIANT* var)
2020 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2022 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2024 if (var == NULL)
2025 return E_INVALIDARG;
2026 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
2028 V_VT(var) = VT_BSTR;
2029 if (This->bUseXPath)
2030 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
2031 else
2032 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
2033 return S_OK;
2036 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2037 return E_FAIL;
2040 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
2042 domdoc_QueryInterface,
2043 domdoc_AddRef,
2044 domdoc_Release,
2045 domdoc_GetTypeInfoCount,
2046 domdoc_GetTypeInfo,
2047 domdoc_GetIDsOfNames,
2048 domdoc_Invoke,
2049 domdoc_get_nodeName,
2050 domdoc_get_nodeValue,
2051 domdoc_put_nodeValue,
2052 domdoc_get_nodeType,
2053 domdoc_get_parentNode,
2054 domdoc_get_childNodes,
2055 domdoc_get_firstChild,
2056 domdoc_get_lastChild,
2057 domdoc_get_previousSibling,
2058 domdoc_get_nextSibling,
2059 domdoc_get_attributes,
2060 domdoc_insertBefore,
2061 domdoc_replaceChild,
2062 domdoc_removeChild,
2063 domdoc_appendChild,
2064 domdoc_hasChildNodes,
2065 domdoc_get_ownerDocument,
2066 domdoc_cloneNode,
2067 domdoc_get_nodeTypeString,
2068 domdoc_get_text,
2069 domdoc_put_text,
2070 domdoc_get_specified,
2071 domdoc_get_definition,
2072 domdoc_get_nodeTypedValue,
2073 domdoc_put_nodeTypedValue,
2074 domdoc_get_dataType,
2075 domdoc_put_dataType,
2076 domdoc_get_xml,
2077 domdoc_transformNode,
2078 domdoc_selectNodes,
2079 domdoc_selectSingleNode,
2080 domdoc_get_parsed,
2081 domdoc_get_namespaceURI,
2082 domdoc_get_prefix,
2083 domdoc_get_baseName,
2084 domdoc_transformNodeToObject,
2085 domdoc_get_doctype,
2086 domdoc_get_implementation,
2087 domdoc_get_documentElement,
2088 domdoc_put_documentElement,
2089 domdoc_createElement,
2090 domdoc_createDocumentFragment,
2091 domdoc_createTextNode,
2092 domdoc_createComment,
2093 domdoc_createCDATASection,
2094 domdoc_createProcessingInstruction,
2095 domdoc_createAttribute,
2096 domdoc_createEntityReference,
2097 domdoc_getElementsByTagName,
2098 domdoc_createNode,
2099 domdoc_nodeFromID,
2100 domdoc_load,
2101 domdoc_get_readyState,
2102 domdoc_get_parseError,
2103 domdoc_get_url,
2104 domdoc_get_async,
2105 domdoc_put_async,
2106 domdoc_abort,
2107 domdoc_loadXML,
2108 domdoc_save,
2109 domdoc_get_validateOnParse,
2110 domdoc_put_validateOnParse,
2111 domdoc_get_resolveExternals,
2112 domdoc_put_resolveExternals,
2113 domdoc_get_preserveWhiteSpace,
2114 domdoc_put_preserveWhiteSpace,
2115 domdoc_put_onReadyStateChange,
2116 domdoc_put_onDataAvailable,
2117 domdoc_put_onTransformNode,
2118 domdoc_get_namespaces,
2119 domdoc_get_schemas,
2120 domdoc_putref_schemas,
2121 domdoc_validate,
2122 domdoc_setProperty,
2123 domdoc_getProperty
2126 /* xmldoc implementation of IObjectWithSite */
2127 static HRESULT WINAPI
2128 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2130 domdoc *This = impl_from_IObjectWithSite(iface);
2131 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2134 static ULONG WINAPI
2135 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2137 domdoc *This = impl_from_IObjectWithSite(iface);
2138 return IXMLDocument_AddRef((IXMLDocument *)This);
2141 static ULONG WINAPI
2142 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2144 domdoc *This = impl_from_IObjectWithSite(iface);
2145 return IXMLDocument_Release((IXMLDocument *)This);
2148 static HRESULT WINAPI
2149 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2151 domdoc *This = impl_from_IObjectWithSite(iface);
2153 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2155 if ( !This->site )
2156 return E_FAIL;
2158 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2161 static HRESULT WINAPI
2162 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2164 domdoc *This = impl_from_IObjectWithSite(iface);
2166 TRACE("(%p)->(%p)\n", iface, punk);
2168 if(!punk)
2170 if(This->site)
2172 IUnknown_Release( This->site );
2173 This->site = NULL;
2176 return S_OK;
2179 if ( punk )
2180 IUnknown_AddRef( punk );
2182 if(This->site)
2183 IUnknown_Release( This->site );
2185 This->site = punk;
2187 return S_OK;
2190 static const IObjectWithSiteVtbl domdocObjectSite =
2192 xmldoc_ObjectWithSite_QueryInterface,
2193 xmldoc_ObjectWithSite_AddRef,
2194 xmldoc_ObjectWithSite_Release,
2195 xmldoc_SetSite,
2196 xmldoc_GetSite,
2199 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2201 domdoc *This = impl_from_IObjectSafety(iface);
2202 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2205 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2207 domdoc *This = impl_from_IObjectSafety(iface);
2208 return IXMLDocument_AddRef((IXMLDocument *)This);
2211 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2213 domdoc *This = impl_from_IObjectSafety(iface);
2214 return IXMLDocument_Release((IXMLDocument *)This);
2217 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2219 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2220 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2222 domdoc *This = impl_from_IObjectSafety(iface);
2224 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2226 if(!pdwSupportedOptions || !pdwEnabledOptions)
2227 return E_POINTER;
2229 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2230 *pdwEnabledOptions = This->safeopt;
2232 return S_OK;
2235 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2236 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2238 domdoc *This = impl_from_IObjectSafety(iface);
2239 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2241 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2242 return E_FAIL;
2244 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2245 return S_OK;
2248 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2249 xmldoc_Safety_QueryInterface,
2250 xmldoc_Safety_AddRef,
2251 xmldoc_Safety_Release,
2252 xmldoc_Safety_GetInterfaceSafetyOptions,
2253 xmldoc_Safety_SetInterfaceSafetyOptions
2257 static const tid_t domdoc_iface_tids[] = {
2258 IXMLDOMNode_tid,
2259 IXMLDOMDocument_tid,
2260 IXMLDOMDocument2_tid,
2263 static dispex_static_data_t domdoc_dispex = {
2264 NULL,
2265 IXMLDOMDocument2_tid,
2266 NULL,
2267 domdoc_iface_tids
2270 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2272 domdoc *doc;
2274 doc = heap_alloc( sizeof (*doc) );
2275 if( !doc )
2276 return E_OUTOFMEMORY;
2278 doc->lpVtbl = &domdoc_vtbl;
2279 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2280 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2281 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2282 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2283 doc->ref = 1;
2284 doc->async = VARIANT_TRUE;
2285 doc->validating = 0;
2286 doc->resolving = 0;
2287 doc->preserving = 0;
2288 doc->bUseXPath = FALSE;
2289 doc->error = S_OK;
2290 doc->schema = NULL;
2291 doc->stream = NULL;
2292 doc->site = NULL;
2293 doc->safeopt = 0;
2294 doc->bsc = NULL;
2296 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2298 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2300 TRACE("returning iface %p\n", *document);
2301 return S_OK;
2304 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2306 xmlDocPtr xmldoc;
2307 HRESULT hr;
2309 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2311 xmldoc = xmlNewDoc(NULL);
2312 if(!xmldoc)
2313 return E_OUTOFMEMORY;
2315 xmldoc->_private = create_priv();
2317 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2318 if(FAILED(hr))
2319 xmlFreeDoc(xmldoc);
2321 return hr;
2324 IUnknown* create_domdoc( xmlNodePtr document )
2326 HRESULT hr;
2327 LPVOID pObj = NULL;
2329 TRACE("(%p)\n", document);
2331 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2332 if (FAILED(hr))
2333 return NULL;
2335 return pObj;
2338 #else
2340 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2342 MESSAGE("This program tried to use a DOMDocument object, but\n"
2343 "libxml2 support was not present at compile time.\n");
2344 return E_NOTIMPL;
2347 #endif