ddraw: Hack to draw to the desktop window.
[wine/hacks.git] / dlls / msxml3 / domdoc.c
blob0007503a2d723d22216b05b945c572f1c00263cf
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 IPersistStreamInitVtbl *lpvtblIPersistStreamInit;
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 /* links a "<?xml" node as a first child */
145 void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
147 assert(doc != NULL);
148 if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
151 /* unlinks a first "<?xml" child if it was created */
152 xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
154 xmlNodePtr node;
156 assert(doc != NULL);
158 if (doc->standalone != -1)
160 node = doc->children;
161 xmlUnlinkNode( node );
163 else
164 node = NULL;
166 return node;
169 static xmlDocPtr doparse( char *ptr, int len, const char *encoding )
171 xmlDocPtr doc;
173 #ifdef HAVE_XMLREADMEMORY
175 * use xmlReadMemory if possible so we can suppress
176 * writing errors to stderr
178 doc = xmlReadMemory( ptr, len, NULL, encoding,
179 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
180 #else
181 doc = xmlParseMemory( ptr, len );
182 #endif
184 /* create first child as a <?xml...?> */
185 if (doc && doc->standalone != -1)
187 xmlNodePtr node;
188 char buff[30];
189 xmlChar *xmlbuff = (xmlChar*)buff;
191 node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
193 /* version attribute can't be omitted */
194 sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
195 xmlNodeAddContent( node, xmlbuff );
197 if (doc->encoding)
199 sprintf(buff, " encoding=\"%s\"", doc->encoding);
200 xmlNodeAddContent( node, xmlbuff );
203 if (doc->standalone != -2)
205 sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
206 xmlNodeAddContent( node, xmlbuff );
209 xmldoc_link_xmldecl( doc, node );
212 return doc;
215 LONG xmldoc_add_ref(xmlDocPtr doc)
217 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
218 TRACE("(%p)->(%d)\n", doc, ref);
219 return ref;
222 LONG xmldoc_release(xmlDocPtr doc)
224 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
225 LONG ref = InterlockedDecrement(&priv->refs);
226 TRACE("(%p)->(%d)\n", doc, ref);
227 if(ref == 0)
229 orphan_entry *orphan, *orphan2;
230 TRACE("freeing docptr %p\n", doc);
232 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
234 xmlFreeNode( orphan->node );
235 heap_free( orphan );
237 heap_free(doc->_private);
239 xmlFreeDoc(doc);
242 return ref;
245 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
247 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
248 orphan_entry *entry;
250 entry = heap_alloc( sizeof (*entry) );
251 if(!entry)
252 return E_OUTOFMEMORY;
254 entry->node = node;
255 list_add_head( &priv->orphans, &entry->entry );
256 return S_OK;
259 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
261 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
262 orphan_entry *entry, *entry2;
264 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
266 if( entry->node == node )
268 list_remove( &entry->entry );
269 heap_free( entry );
270 return S_OK;
274 return S_FALSE;
277 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
279 if(node->node)
280 xmldoc_release(node->node->doc);
282 node->node = (xmlNodePtr) xml;
283 if(node->node)
284 xmldoc_add_ref(node->node->doc);
286 return S_OK;
289 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
291 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
294 static inline xmlDocPtr get_doc( domdoc *This )
296 return (xmlDocPtr)This->node.node;
299 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
301 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
304 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
306 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
309 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
311 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
314 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
316 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
319 /************************************************************************
320 * domdoc implementation of IPersistStream.
322 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
323 IPersistStreamInit *iface, REFIID riid, void **ppvObj)
325 domdoc *this = impl_from_IPersistStreamInit(iface);
326 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
329 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
330 IPersistStreamInit *iface)
332 domdoc *this = impl_from_IPersistStreamInit(iface);
333 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
336 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
337 IPersistStreamInit *iface)
339 domdoc *this = impl_from_IPersistStreamInit(iface);
340 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
343 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
344 IPersistStreamInit *iface, CLSID *classid)
346 TRACE("(%p,%p): stub!\n", iface, classid);
348 if(!classid)
349 return E_POINTER;
351 *classid = CLSID_DOMDocument2;
353 return S_OK;
356 static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
357 IPersistStreamInit *iface)
359 domdoc *This = impl_from_IPersistStreamInit(iface);
360 FIXME("(%p): stub!\n", This);
361 return S_FALSE;
364 static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
365 IPersistStreamInit *iface, LPSTREAM pStm)
367 domdoc *This = impl_from_IPersistStreamInit(iface);
368 HRESULT hr;
369 HGLOBAL hglobal;
370 DWORD read, written, len;
371 BYTE buf[4096];
372 char *ptr;
373 xmlDocPtr xmldoc = NULL;
375 TRACE("(%p)->(%p)\n", This, pStm);
377 if (!pStm)
378 return E_INVALIDARG;
380 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
381 if (FAILED(hr))
382 return hr;
386 IStream_Read(pStm, buf, sizeof(buf), &read);
387 hr = IStream_Write(This->stream, buf, read, &written);
388 } while(SUCCEEDED(hr) && written != 0 && read != 0);
390 if (FAILED(hr))
392 ERR("Failed to copy stream\n");
393 return hr;
396 hr = GetHGlobalFromStream(This->stream, &hglobal);
397 if (FAILED(hr))
398 return hr;
400 len = GlobalSize(hglobal);
401 ptr = GlobalLock(hglobal);
402 if (len != 0)
403 xmldoc = doparse(ptr, len, NULL);
404 GlobalUnlock(hglobal);
406 if (!xmldoc)
408 ERR("Failed to parse xml\n");
409 return E_FAIL;
412 xmldoc->_private = create_priv();
414 return attach_xmldoc( &This->node, xmldoc );
417 static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
418 IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty)
420 domdoc *This = impl_from_IPersistStreamInit(iface);
421 HRESULT hr;
422 BSTR xmlString;
424 TRACE("(%p)->(%p %d)\n", This, pStm, fClearDirty);
426 hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &xmlString );
427 if(hr == S_OK)
429 DWORD count;
430 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
432 hr = IStream_Write( pStm, xmlString, len, &count );
434 SysFreeString(xmlString);
437 TRACE("ret 0x%08x\n", hr);
439 return hr;
442 static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
443 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
445 domdoc *This = impl_from_IPersistStreamInit(iface);
446 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
447 return E_NOTIMPL;
450 static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
451 IPersistStreamInit *iface)
453 domdoc *This = impl_from_IPersistStreamInit(iface);
454 TRACE("(%p)\n", This);
455 return S_OK;
458 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
460 domdoc_IPersistStreamInit_QueryInterface,
461 domdoc_IPersistStreamInit_AddRef,
462 domdoc_IPersistStreamInit_Release,
463 domdoc_IPersistStreamInit_GetClassID,
464 domdoc_IPersistStreamInit_IsDirty,
465 domdoc_IPersistStreamInit_Load,
466 domdoc_IPersistStreamInit_Save,
467 domdoc_IPersistStreamInit_GetSizeMax,
468 domdoc_IPersistStreamInit_InitNew
471 /* ISupportErrorInfo interface */
472 static HRESULT WINAPI support_error_QueryInterface(
473 ISupportErrorInfo *iface,
474 REFIID riid, void** ppvObj )
476 domdoc *This = impl_from_ISupportErrorInfo(iface);
477 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)This, riid, ppvObj);
480 static ULONG WINAPI support_error_AddRef(
481 ISupportErrorInfo *iface )
483 domdoc *This = impl_from_ISupportErrorInfo(iface);
484 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)This);
487 static ULONG WINAPI support_error_Release(
488 ISupportErrorInfo *iface )
490 domdoc *This = impl_from_ISupportErrorInfo(iface);
491 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)This);
494 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
495 ISupportErrorInfo *iface,
496 REFIID riid )
498 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
499 return S_FALSE;
502 static const struct ISupportErrorInfoVtbl support_error_vtbl =
504 support_error_QueryInterface,
505 support_error_AddRef,
506 support_error_Release,
507 support_error_InterfaceSupportsErrorInfo
510 /* IXMLDOMDocument2 interface */
511 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
513 domdoc *This = impl_from_IXMLDOMDocument2( iface );
515 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
517 *ppvObject = NULL;
519 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
520 IsEqualGUID( riid, &IID_IDispatch ) ||
521 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
522 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
524 *ppvObject = iface;
526 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
528 *ppvObject = IXMLDOMNode_from_impl(&This->node);
530 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
531 IsEqualGUID(&IID_IPersistStreamInit, riid))
533 *ppvObject = &(This->lpvtblIPersistStreamInit);
535 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
537 *ppvObject = &(This->lpvtblIObjectWithSite);
539 else if (IsEqualGUID(&IID_IObjectSafety, riid))
541 *ppvObject = &(This->lpvtblIObjectSafety);
543 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
545 *ppvObject = &This->lpvtblISupportErrorInfo;
547 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
549 return *ppvObject ? S_OK : E_NOINTERFACE;
551 else if(IsEqualGUID(&IID_IRunnableObject, riid))
553 TRACE("IID_IRunnableObject not supported returning NULL\n");
554 return E_NOINTERFACE;
556 else
558 FIXME("interface %s not implemented\n", debugstr_guid(riid));
559 return E_NOINTERFACE;
562 IUnknown_AddRef((IUnknown*)*ppvObject);
564 return S_OK;
568 static ULONG WINAPI domdoc_AddRef(
569 IXMLDOMDocument2 *iface )
571 domdoc *This = impl_from_IXMLDOMDocument2( iface );
572 TRACE("%p\n", This );
573 return InterlockedIncrement( &This->ref );
577 static ULONG WINAPI domdoc_Release(
578 IXMLDOMDocument2 *iface )
580 domdoc *This = impl_from_IXMLDOMDocument2( iface );
581 LONG ref;
583 TRACE("%p\n", This );
585 ref = InterlockedDecrement( &This->ref );
586 if ( ref == 0 )
588 if(This->bsc)
589 detach_bsc(This->bsc);
591 if (This->site)
592 IUnknown_Release( This->site );
593 destroy_xmlnode(&This->node);
594 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
595 if (This->stream) IStream_Release(This->stream);
596 HeapFree( GetProcessHeap(), 0, This );
599 return ref;
602 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
604 domdoc *This = impl_from_IXMLDOMDocument2( iface );
606 TRACE("(%p)->(%p)\n", This, pctinfo);
608 *pctinfo = 1;
610 return S_OK;
613 static HRESULT WINAPI domdoc_GetTypeInfo(
614 IXMLDOMDocument2 *iface,
615 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
617 domdoc *This = impl_from_IXMLDOMDocument2( iface );
618 HRESULT hr;
620 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
622 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
624 return hr;
627 static HRESULT WINAPI domdoc_GetIDsOfNames(
628 IXMLDOMDocument2 *iface,
629 REFIID riid,
630 LPOLESTR* rgszNames,
631 UINT cNames,
632 LCID lcid,
633 DISPID* rgDispId)
635 domdoc *This = impl_from_IXMLDOMDocument2( iface );
636 ITypeInfo *typeinfo;
637 HRESULT hr;
639 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
640 lcid, rgDispId);
642 if(!rgszNames || cNames == 0 || !rgDispId)
643 return E_INVALIDARG;
645 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
646 if(SUCCEEDED(hr))
648 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
649 ITypeInfo_Release(typeinfo);
652 return hr;
656 static HRESULT WINAPI domdoc_Invoke(
657 IXMLDOMDocument2 *iface,
658 DISPID dispIdMember,
659 REFIID riid,
660 LCID lcid,
661 WORD wFlags,
662 DISPPARAMS* pDispParams,
663 VARIANT* pVarResult,
664 EXCEPINFO* pExcepInfo,
665 UINT* puArgErr)
667 domdoc *This = impl_from_IXMLDOMDocument2( iface );
668 ITypeInfo *typeinfo;
669 HRESULT hr;
671 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
672 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
674 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
675 if(SUCCEEDED(hr))
677 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
678 pVarResult, pExcepInfo, puArgErr);
679 ITypeInfo_Release(typeinfo);
682 return hr;
686 static HRESULT WINAPI domdoc_get_nodeName(
687 IXMLDOMDocument2 *iface,
688 BSTR* name )
690 domdoc *This = impl_from_IXMLDOMDocument2( iface );
691 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
695 static HRESULT WINAPI domdoc_get_nodeValue(
696 IXMLDOMDocument2 *iface,
697 VARIANT* value )
699 domdoc *This = impl_from_IXMLDOMDocument2( iface );
700 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
704 static HRESULT WINAPI domdoc_put_nodeValue(
705 IXMLDOMDocument2 *iface,
706 VARIANT value)
708 domdoc *This = impl_from_IXMLDOMDocument2( iface );
709 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
713 static HRESULT WINAPI domdoc_get_nodeType(
714 IXMLDOMDocument2 *iface,
715 DOMNodeType* type )
717 domdoc *This = impl_from_IXMLDOMDocument2( iface );
718 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
722 static HRESULT WINAPI domdoc_get_parentNode(
723 IXMLDOMDocument2 *iface,
724 IXMLDOMNode** parent )
726 domdoc *This = impl_from_IXMLDOMDocument2( iface );
727 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
731 static HRESULT WINAPI domdoc_get_childNodes(
732 IXMLDOMDocument2 *iface,
733 IXMLDOMNodeList** childList )
735 domdoc *This = impl_from_IXMLDOMDocument2( iface );
736 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
740 static HRESULT WINAPI domdoc_get_firstChild(
741 IXMLDOMDocument2 *iface,
742 IXMLDOMNode** firstChild )
744 domdoc *This = impl_from_IXMLDOMDocument2( iface );
745 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
749 static HRESULT WINAPI domdoc_get_lastChild(
750 IXMLDOMDocument2 *iface,
751 IXMLDOMNode** lastChild )
753 domdoc *This = impl_from_IXMLDOMDocument2( iface );
754 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
758 static HRESULT WINAPI domdoc_get_previousSibling(
759 IXMLDOMDocument2 *iface,
760 IXMLDOMNode** previousSibling )
762 domdoc *This = impl_from_IXMLDOMDocument2( iface );
763 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
767 static HRESULT WINAPI domdoc_get_nextSibling(
768 IXMLDOMDocument2 *iface,
769 IXMLDOMNode** nextSibling )
771 domdoc *This = impl_from_IXMLDOMDocument2( iface );
772 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
776 static HRESULT WINAPI domdoc_get_attributes(
777 IXMLDOMDocument2 *iface,
778 IXMLDOMNamedNodeMap** attributeMap )
780 domdoc *This = impl_from_IXMLDOMDocument2( iface );
781 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
785 static HRESULT WINAPI domdoc_insertBefore(
786 IXMLDOMDocument2 *iface,
787 IXMLDOMNode* newChild,
788 VARIANT refChild,
789 IXMLDOMNode** outNewChild )
791 domdoc *This = impl_from_IXMLDOMDocument2( iface );
792 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
796 static HRESULT WINAPI domdoc_replaceChild(
797 IXMLDOMDocument2 *iface,
798 IXMLDOMNode* newChild,
799 IXMLDOMNode* oldChild,
800 IXMLDOMNode** outOldChild)
802 domdoc *This = impl_from_IXMLDOMDocument2( iface );
803 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
807 static HRESULT WINAPI domdoc_removeChild(
808 IXMLDOMDocument2 *iface,
809 IXMLDOMNode* childNode,
810 IXMLDOMNode** oldChild)
812 domdoc *This = impl_from_IXMLDOMDocument2( iface );
813 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
817 static HRESULT WINAPI domdoc_appendChild(
818 IXMLDOMDocument2 *iface,
819 IXMLDOMNode* newChild,
820 IXMLDOMNode** outNewChild)
822 domdoc *This = impl_from_IXMLDOMDocument2( iface );
823 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
827 static HRESULT WINAPI domdoc_hasChildNodes(
828 IXMLDOMDocument2 *iface,
829 VARIANT_BOOL* hasChild)
831 domdoc *This = impl_from_IXMLDOMDocument2( iface );
832 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
836 static HRESULT WINAPI domdoc_get_ownerDocument(
837 IXMLDOMDocument2 *iface,
838 IXMLDOMDocument** DOMDocument)
840 domdoc *This = impl_from_IXMLDOMDocument2( iface );
841 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
845 static HRESULT WINAPI domdoc_cloneNode(
846 IXMLDOMDocument2 *iface,
847 VARIANT_BOOL deep,
848 IXMLDOMNode** cloneRoot)
850 domdoc *This = impl_from_IXMLDOMDocument2( iface );
851 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
855 static HRESULT WINAPI domdoc_get_nodeTypeString(
856 IXMLDOMDocument2 *iface,
857 BSTR* nodeType )
859 domdoc *This = impl_from_IXMLDOMDocument2( iface );
860 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
864 static HRESULT WINAPI domdoc_get_text(
865 IXMLDOMDocument2 *iface,
866 BSTR* text )
868 domdoc *This = impl_from_IXMLDOMDocument2( iface );
869 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
873 static HRESULT WINAPI domdoc_put_text(
874 IXMLDOMDocument2 *iface,
875 BSTR text )
877 domdoc *This = impl_from_IXMLDOMDocument2( iface );
878 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
882 static HRESULT WINAPI domdoc_get_specified(
883 IXMLDOMDocument2 *iface,
884 VARIANT_BOOL* isSpecified )
886 domdoc *This = impl_from_IXMLDOMDocument2( iface );
887 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
891 static HRESULT WINAPI domdoc_get_definition(
892 IXMLDOMDocument2 *iface,
893 IXMLDOMNode** definitionNode )
895 domdoc *This = impl_from_IXMLDOMDocument2( iface );
896 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
900 static HRESULT WINAPI domdoc_get_nodeTypedValue(
901 IXMLDOMDocument2 *iface,
902 VARIANT* typedValue )
904 domdoc *This = impl_from_IXMLDOMDocument2( iface );
905 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
908 static HRESULT WINAPI domdoc_put_nodeTypedValue(
909 IXMLDOMDocument2 *iface,
910 VARIANT typedValue )
912 domdoc *This = impl_from_IXMLDOMDocument2( iface );
913 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
917 static HRESULT WINAPI domdoc_get_dataType(
918 IXMLDOMDocument2 *iface,
919 VARIANT* dataTypeName )
921 domdoc *This = impl_from_IXMLDOMDocument2( iface );
922 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
926 static HRESULT WINAPI domdoc_put_dataType(
927 IXMLDOMDocument2 *iface,
928 BSTR dataTypeName )
930 domdoc *This = impl_from_IXMLDOMDocument2( iface );
931 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
935 static HRESULT WINAPI domdoc_get_xml(
936 IXMLDOMDocument2 *iface,
937 BSTR* xmlString )
939 domdoc *This = impl_from_IXMLDOMDocument2( iface );
940 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
944 static HRESULT WINAPI domdoc_transformNode(
945 IXMLDOMDocument2 *iface,
946 IXMLDOMNode* styleSheet,
947 BSTR* xmlString )
949 domdoc *This = impl_from_IXMLDOMDocument2( iface );
950 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
954 static HRESULT WINAPI domdoc_selectNodes(
955 IXMLDOMDocument2 *iface,
956 BSTR queryString,
957 IXMLDOMNodeList** resultList )
959 domdoc *This = impl_from_IXMLDOMDocument2( iface );
960 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
964 static HRESULT WINAPI domdoc_selectSingleNode(
965 IXMLDOMDocument2 *iface,
966 BSTR queryString,
967 IXMLDOMNode** resultNode )
969 domdoc *This = impl_from_IXMLDOMDocument2( iface );
970 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
974 static HRESULT WINAPI domdoc_get_parsed(
975 IXMLDOMDocument2 *iface,
976 VARIANT_BOOL* isParsed )
978 domdoc *This = impl_from_IXMLDOMDocument2( iface );
979 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
983 static HRESULT WINAPI domdoc_get_namespaceURI(
984 IXMLDOMDocument2 *iface,
985 BSTR* namespaceURI )
987 domdoc *This = impl_from_IXMLDOMDocument2( iface );
988 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
992 static HRESULT WINAPI domdoc_get_prefix(
993 IXMLDOMDocument2 *iface,
994 BSTR* prefixString )
996 domdoc *This = impl_from_IXMLDOMDocument2( iface );
997 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1001 static HRESULT WINAPI domdoc_get_baseName(
1002 IXMLDOMDocument2 *iface,
1003 BSTR* nameString )
1005 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1006 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1010 static HRESULT WINAPI domdoc_transformNodeToObject(
1011 IXMLDOMDocument2 *iface,
1012 IXMLDOMNode* stylesheet,
1013 VARIANT outputObject)
1015 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1016 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1020 static HRESULT WINAPI domdoc_get_doctype(
1021 IXMLDOMDocument2 *iface,
1022 IXMLDOMDocumentType** documentType )
1024 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1025 FIXME("(%p)\n", This);
1026 return E_NOTIMPL;
1030 static HRESULT WINAPI domdoc_get_implementation(
1031 IXMLDOMDocument2 *iface,
1032 IXMLDOMImplementation** impl )
1034 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1036 TRACE("(%p)->(%p)\n", This, impl);
1038 if(!impl)
1039 return E_INVALIDARG;
1041 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1043 return S_OK;
1046 static HRESULT WINAPI domdoc_get_documentElement(
1047 IXMLDOMDocument2 *iface,
1048 IXMLDOMElement** DOMElement )
1050 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1051 xmlDocPtr xmldoc = NULL;
1052 xmlNodePtr root = NULL;
1053 IXMLDOMNode *element_node;
1054 HRESULT hr;
1056 TRACE("(%p)->(%p)\n", This, DOMElement);
1058 if(!DOMElement)
1059 return E_INVALIDARG;
1061 *DOMElement = NULL;
1063 xmldoc = get_doc( This );
1065 root = xmlDocGetRootElement( xmldoc );
1066 if ( !root )
1067 return S_FALSE;
1069 element_node = create_node( root );
1070 if(!element_node) return S_FALSE;
1072 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
1073 IXMLDOMNode_Release(element_node);
1075 return hr;
1079 static HRESULT WINAPI domdoc_put_documentElement(
1080 IXMLDOMDocument2 *iface,
1081 IXMLDOMElement* DOMElement )
1083 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1084 IXMLDOMNode *elementNode;
1085 xmlNodePtr oldRoot;
1086 xmlnode *xmlNode;
1087 HRESULT hr;
1089 TRACE("(%p)->(%p)\n", This, DOMElement);
1091 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1092 if(FAILED(hr))
1093 return hr;
1095 xmlNode = impl_from_IXMLDOMNode( elementNode );
1097 if(!xmlNode->node->parent)
1098 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1099 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1101 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1102 IXMLDOMNode_Release( elementNode );
1104 if(oldRoot)
1105 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1107 return S_OK;
1111 static HRESULT WINAPI domdoc_createElement(
1112 IXMLDOMDocument2 *iface,
1113 BSTR tagname,
1114 IXMLDOMElement** element )
1116 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1117 IXMLDOMNode *node;
1118 VARIANT type;
1119 HRESULT hr;
1121 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1123 if (!element || !tagname) return E_INVALIDARG;
1125 V_VT(&type) = VT_I1;
1126 V_I1(&type) = NODE_ELEMENT;
1128 hr = IXMLDOMDocument2_createNode(iface, type, tagname, NULL, &node);
1129 if (hr == S_OK)
1131 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1132 IXMLDOMNode_Release(node);
1135 return hr;
1139 static HRESULT WINAPI domdoc_createDocumentFragment(
1140 IXMLDOMDocument2 *iface,
1141 IXMLDOMDocumentFragment** frag )
1143 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1144 IXMLDOMNode *node;
1145 VARIANT type;
1146 HRESULT hr;
1148 TRACE("(%p)->(%p)\n", This, frag);
1150 if (!frag) return E_INVALIDARG;
1152 *frag = NULL;
1154 V_VT(&type) = VT_I1;
1155 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1157 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1158 if (hr == S_OK)
1160 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1161 IXMLDOMNode_Release(node);
1164 return hr;
1168 static HRESULT WINAPI domdoc_createTextNode(
1169 IXMLDOMDocument2 *iface,
1170 BSTR data,
1171 IXMLDOMText** text )
1173 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1174 IXMLDOMNode *node;
1175 VARIANT type;
1176 HRESULT hr;
1178 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1180 if (!text) return E_INVALIDARG;
1182 *text = NULL;
1184 V_VT(&type) = VT_I1;
1185 V_I1(&type) = NODE_TEXT;
1187 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1188 if (hr == S_OK)
1190 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1191 IXMLDOMNode_Release(node);
1192 hr = IXMLDOMText_put_data(*text, data);
1195 return hr;
1199 static HRESULT WINAPI domdoc_createComment(
1200 IXMLDOMDocument2 *iface,
1201 BSTR data,
1202 IXMLDOMComment** comment )
1204 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1205 VARIANT type;
1206 HRESULT hr;
1207 IXMLDOMNode *node;
1209 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1211 if (!comment) return E_INVALIDARG;
1213 *comment = NULL;
1215 V_VT(&type) = VT_I1;
1216 V_I1(&type) = NODE_COMMENT;
1218 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1219 if (hr == S_OK)
1221 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1222 IXMLDOMNode_Release(node);
1223 hr = IXMLDOMComment_put_data(*comment, data);
1226 return hr;
1230 static HRESULT WINAPI domdoc_createCDATASection(
1231 IXMLDOMDocument2 *iface,
1232 BSTR data,
1233 IXMLDOMCDATASection** cdata )
1235 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1236 IXMLDOMNode *node;
1237 VARIANT type;
1238 HRESULT hr;
1240 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1242 if (!cdata) return E_INVALIDARG;
1244 *cdata = NULL;
1246 V_VT(&type) = VT_I1;
1247 V_I1(&type) = NODE_CDATA_SECTION;
1249 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1250 if (hr == S_OK)
1252 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1253 IXMLDOMNode_Release(node);
1254 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1257 return hr;
1261 static HRESULT WINAPI domdoc_createProcessingInstruction(
1262 IXMLDOMDocument2 *iface,
1263 BSTR target,
1264 BSTR data,
1265 IXMLDOMProcessingInstruction** pi )
1267 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1268 IXMLDOMNode *node;
1269 VARIANT type;
1270 HRESULT hr;
1272 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1274 if (!pi) return E_INVALIDARG;
1276 *pi = NULL;
1278 V_VT(&type) = VT_I1;
1279 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1281 hr = IXMLDOMDocument2_createNode(iface, type, target, NULL, &node);
1282 if (hr == S_OK)
1284 VARIANT v_data;
1286 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1287 V_VT(&v_data) = VT_BSTR;
1288 V_BSTR(&v_data) = data;
1290 hr = IXMLDOMNode_put_nodeValue( node, v_data );
1292 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1293 IXMLDOMNode_Release(node);
1296 return hr;
1300 static HRESULT WINAPI domdoc_createAttribute(
1301 IXMLDOMDocument2 *iface,
1302 BSTR name,
1303 IXMLDOMAttribute** attribute )
1305 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1306 IXMLDOMNode *node;
1307 VARIANT type;
1308 HRESULT hr;
1310 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1312 if (!attribute || !name) return E_INVALIDARG;
1314 V_VT(&type) = VT_I1;
1315 V_I1(&type) = NODE_ATTRIBUTE;
1317 hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
1318 if (hr == S_OK)
1320 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1321 IXMLDOMNode_Release(node);
1324 return hr;
1328 static HRESULT WINAPI domdoc_createEntityReference(
1329 IXMLDOMDocument2 *iface,
1330 BSTR name,
1331 IXMLDOMEntityReference** entityref )
1333 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1334 IXMLDOMNode *node;
1335 VARIANT type;
1336 HRESULT hr;
1338 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1340 if (!entityref) return E_INVALIDARG;
1342 *entityref = NULL;
1344 V_VT(&type) = VT_I1;
1345 V_I1(&type) = NODE_ENTITY_REFERENCE;
1347 hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
1348 if (hr == S_OK)
1350 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1351 IXMLDOMNode_Release(node);
1354 return hr;
1358 static HRESULT WINAPI domdoc_getElementsByTagName(
1359 IXMLDOMDocument2 *iface,
1360 BSTR tagName,
1361 IXMLDOMNodeList** resultList )
1363 static const WCHAR xpathformat[] =
1364 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1365 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1366 LPWSTR szPattern;
1367 HRESULT hr;
1368 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1370 if (tagName[0] == '*' && tagName[1] == 0)
1372 szPattern = heap_alloc(sizeof(WCHAR)*4);
1373 szPattern[0] = szPattern[1] = '/';
1374 szPattern[2] = '*';
1375 szPattern[3] = 0;
1377 else
1379 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1380 wsprintfW(szPattern, xpathformat, tagName);
1383 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1384 heap_free(szPattern);
1386 return hr;
1389 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1391 VARIANT tmp;
1392 HRESULT hr;
1394 VariantInit(&tmp);
1395 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1396 if(FAILED(hr))
1397 return E_INVALIDARG;
1399 *type = V_I4(&tmp);
1401 return S_OK;
1404 static HRESULT WINAPI domdoc_createNode(
1405 IXMLDOMDocument2 *iface,
1406 VARIANT Type,
1407 BSTR name,
1408 BSTR namespaceURI,
1409 IXMLDOMNode** node )
1411 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1412 DOMNodeType node_type;
1413 xmlNodePtr xmlnode;
1414 xmlChar *xml_name;
1415 HRESULT hr;
1417 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1419 if(!node) return E_INVALIDARG;
1421 if(namespaceURI && namespaceURI[0])
1422 FIXME("nodes with namespaces currently not supported.\n");
1424 hr = get_node_type(Type, &node_type);
1425 if(FAILED(hr)) return hr;
1427 TRACE("node_type %d\n", node_type);
1429 /* exit earlier for types that need name */
1430 switch(node_type)
1432 case NODE_ELEMENT:
1433 case NODE_ATTRIBUTE:
1434 case NODE_ENTITY_REFERENCE:
1435 case NODE_PROCESSING_INSTRUCTION:
1436 if (!name || *name == 0) return E_FAIL;
1437 default:
1438 break;
1441 xml_name = xmlChar_from_wchar(name);
1443 switch(node_type)
1445 case NODE_ELEMENT:
1446 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1447 break;
1448 case NODE_ATTRIBUTE:
1449 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1450 break;
1451 case NODE_TEXT:
1452 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1453 break;
1454 case NODE_CDATA_SECTION:
1455 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1456 break;
1457 case NODE_ENTITY_REFERENCE:
1458 xmlnode = xmlNewReference(get_doc(This), xml_name);
1459 break;
1460 case NODE_PROCESSING_INSTRUCTION:
1461 #ifdef HAVE_XMLNEWDOCPI
1462 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1463 #else
1464 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1465 xmlnode = NULL;
1466 #endif
1467 break;
1468 case NODE_COMMENT:
1469 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1470 break;
1471 case NODE_DOCUMENT_FRAGMENT:
1472 xmlnode = xmlNewDocFragment(get_doc(This));
1473 break;
1474 /* unsupported types */
1475 case NODE_DOCUMENT:
1476 case NODE_DOCUMENT_TYPE:
1477 case NODE_ENTITY:
1478 case NODE_NOTATION:
1479 heap_free(xml_name);
1480 return E_INVALIDARG;
1481 default:
1482 FIXME("unhandled node type %d\n", node_type);
1483 xmlnode = NULL;
1484 break;
1487 *node = create_node(xmlnode);
1488 heap_free(xml_name);
1490 if(*node)
1492 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1493 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1494 return S_OK;
1497 return E_FAIL;
1500 static HRESULT WINAPI domdoc_nodeFromID(
1501 IXMLDOMDocument2 *iface,
1502 BSTR idString,
1503 IXMLDOMNode** node )
1505 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1506 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1507 return E_NOTIMPL;
1510 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1512 domdoc *This = obj;
1513 xmlDocPtr xmldoc;
1515 xmldoc = doparse( ptr, len, NULL );
1516 if(xmldoc) {
1517 xmldoc->_private = create_priv();
1518 return attach_xmldoc(&This->node, xmldoc);
1521 return S_OK;
1524 static HRESULT doread( domdoc *This, LPWSTR filename )
1526 bsc_t *bsc;
1527 HRESULT hr;
1529 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1530 if(FAILED(hr))
1531 return hr;
1533 if(This->bsc)
1534 detach_bsc(This->bsc);
1536 This->bsc = bsc;
1537 return S_OK;
1540 static HRESULT WINAPI domdoc_load(
1541 IXMLDOMDocument2 *iface,
1542 VARIANT xmlSource,
1543 VARIANT_BOOL* isSuccessful )
1545 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1546 LPWSTR filename = NULL;
1547 HRESULT hr = S_FALSE;
1548 IXMLDOMDocument2 *pNewDoc = NULL;
1549 IStream *pStream = NULL;
1550 xmlDocPtr xmldoc;
1552 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1554 *isSuccessful = VARIANT_FALSE;
1556 assert( &This->node );
1558 switch( V_VT(&xmlSource) )
1560 case VT_BSTR:
1561 filename = V_BSTR(&xmlSource);
1562 break;
1563 case VT_UNKNOWN:
1564 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1565 if(hr == S_OK)
1567 if(pNewDoc)
1569 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1570 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1571 hr = attach_xmldoc(&This->node, xmldoc);
1573 if(SUCCEEDED(hr))
1574 *isSuccessful = VARIANT_TRUE;
1576 return hr;
1579 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1580 if(hr == S_OK)
1582 IPersistStream *pDocStream;
1583 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1584 if(hr == S_OK)
1586 hr = IPersistStream_Load(pDocStream, pStream);
1587 IStream_Release(pStream);
1588 if(hr == S_OK)
1590 *isSuccessful = VARIANT_TRUE;
1592 TRACE("Using IStream to load Document\n");
1593 return S_OK;
1595 else
1597 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1600 else
1602 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1605 else
1607 /* ISequentialStream */
1608 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1610 break;
1611 default:
1612 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1615 TRACE("filename (%s)\n", debugstr_w(filename));
1617 if ( filename )
1619 hr = doread( This, filename );
1621 if ( FAILED(hr) )
1622 This->error = E_FAIL;
1623 else
1625 hr = This->error = S_OK;
1626 *isSuccessful = VARIANT_TRUE;
1630 if(!filename || FAILED(hr)) {
1631 xmldoc = xmlNewDoc(NULL);
1632 xmldoc->_private = create_priv();
1633 hr = attach_xmldoc(&This->node, xmldoc);
1634 if(SUCCEEDED(hr))
1635 hr = S_FALSE;
1638 TRACE("ret (%d)\n", hr);
1640 return hr;
1644 static HRESULT WINAPI domdoc_get_readyState(
1645 IXMLDOMDocument2 *iface,
1646 LONG *value )
1648 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1649 FIXME("(%p)->(%p)\n", This, value);
1650 return E_NOTIMPL;
1654 static HRESULT WINAPI domdoc_get_parseError(
1655 IXMLDOMDocument2 *iface,
1656 IXMLDOMParseError** errorObj )
1658 BSTR error_string = NULL;
1659 static const WCHAR err[] = {'e','r','r','o','r',0};
1660 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1662 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1664 if(This->error)
1665 error_string = SysAllocString(err);
1667 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1668 if(!*errorObj) return E_OUTOFMEMORY;
1669 return S_OK;
1673 static HRESULT WINAPI domdoc_get_url(
1674 IXMLDOMDocument2 *iface,
1675 BSTR* urlString )
1677 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1678 FIXME("(%p)->(%p)\n", This, urlString);
1679 return E_NOTIMPL;
1683 static HRESULT WINAPI domdoc_get_async(
1684 IXMLDOMDocument2 *iface,
1685 VARIANT_BOOL* isAsync )
1687 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1689 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1690 *isAsync = This->async;
1691 return S_OK;
1695 static HRESULT WINAPI domdoc_put_async(
1696 IXMLDOMDocument2 *iface,
1697 VARIANT_BOOL isAsync )
1699 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1701 TRACE("(%p)->(%d)\n", This, isAsync);
1702 This->async = isAsync;
1703 return S_OK;
1707 static HRESULT WINAPI domdoc_abort(
1708 IXMLDOMDocument2 *iface )
1710 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1711 FIXME("%p\n", This);
1712 return E_NOTIMPL;
1716 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1718 UINT len;
1719 LPSTR str;
1721 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1722 str = heap_alloc( len );
1723 if ( !str )
1724 return FALSE;
1725 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
1726 *plen = len;
1727 *pstr = str;
1728 return TRUE;
1731 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
1732 static HRESULT WINAPI domdoc_loadXML(
1733 IXMLDOMDocument2 *iface,
1734 BSTR bstrXML,
1735 VARIANT_BOOL* isSuccessful )
1737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1738 xmlDocPtr xmldoc = NULL;
1739 char *str;
1740 int len;
1741 HRESULT hr = S_FALSE, hr2;
1743 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
1745 assert ( &This->node );
1747 if ( isSuccessful )
1749 *isSuccessful = VARIANT_FALSE;
1751 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1753 xmldoc = doparse( str, len, "UTF-8" );
1754 heap_free( str );
1755 if ( !xmldoc )
1756 This->error = E_FAIL;
1757 else
1759 hr = This->error = S_OK;
1760 *isSuccessful = VARIANT_TRUE;
1764 if(!xmldoc)
1765 xmldoc = xmlNewDoc(NULL);
1767 xmldoc->_private = create_priv();
1768 hr2 = attach_xmldoc( &This->node, xmldoc );
1769 if( FAILED(hr2) )
1770 hr = hr2;
1772 return hr;
1775 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1776 int len)
1778 DWORD written = -1;
1780 if(!WriteFile(ctx, buffer, len, &written, NULL))
1782 WARN("write error\n");
1783 return -1;
1785 else
1786 return written;
1789 static int XMLCALL domdoc_save_closecallback(void *ctx)
1791 return CloseHandle(ctx) ? 0 : -1;
1794 static HRESULT WINAPI domdoc_save(
1795 IXMLDOMDocument2 *iface,
1796 VARIANT destination )
1798 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1799 HANDLE handle;
1800 xmlSaveCtxtPtr ctx;
1801 xmlNodePtr xmldecl;
1802 HRESULT ret = S_OK;
1804 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1805 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1807 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1809 FIXME("Unhandled vt %d\n", V_VT(&destination));
1810 return S_FALSE;
1813 if(V_VT(&destination) == VT_UNKNOWN)
1815 IUnknown *pUnk = V_UNKNOWN(&destination);
1816 IXMLDOMDocument2 *pDocument;
1818 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1819 if(ret == S_OK)
1821 BSTR bXML;
1822 VARIANT_BOOL bSuccessful;
1824 ret = IXMLDOMDocument2_get_xml(iface, &bXML);
1825 if(ret == S_OK)
1827 ret = IXMLDOMDocument2_loadXML(pDocument, bXML, &bSuccessful);
1829 SysFreeString(bXML);
1832 IXMLDOMDocument2_Release(pDocument);
1835 TRACE("ret %d\n", ret);
1837 return ret;
1840 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1841 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1842 if( handle == INVALID_HANDLE_VALUE )
1844 WARN("failed to create file\n");
1845 return S_FALSE;
1848 /* disable top XML declaration */
1849 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1850 handle, NULL, XML_SAVE_NO_DECL);
1851 if (!ctx)
1853 CloseHandle(handle);
1854 return S_FALSE;
1857 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
1858 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1859 xmldoc_link_xmldecl(get_doc(This), xmldecl);
1861 /* will close file through close callback */
1862 xmlSaveClose(ctx);
1864 return ret;
1867 static HRESULT WINAPI domdoc_get_validateOnParse(
1868 IXMLDOMDocument2 *iface,
1869 VARIANT_BOOL* isValidating )
1871 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1873 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
1874 *isValidating = This->validating;
1875 return S_OK;
1879 static HRESULT WINAPI domdoc_put_validateOnParse(
1880 IXMLDOMDocument2 *iface,
1881 VARIANT_BOOL isValidating )
1883 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1885 TRACE("(%p)->(%d)\n", This, isValidating);
1886 This->validating = isValidating;
1887 return S_OK;
1891 static HRESULT WINAPI domdoc_get_resolveExternals(
1892 IXMLDOMDocument2 *iface,
1893 VARIANT_BOOL* isResolving )
1895 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1897 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
1898 *isResolving = This->resolving;
1899 return S_OK;
1903 static HRESULT WINAPI domdoc_put_resolveExternals(
1904 IXMLDOMDocument2 *iface,
1905 VARIANT_BOOL isResolving )
1907 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1909 TRACE("(%p)->(%d)\n", This, isResolving);
1910 This->resolving = isResolving;
1911 return S_OK;
1915 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1916 IXMLDOMDocument2 *iface,
1917 VARIANT_BOOL* isPreserving )
1919 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1921 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
1922 *isPreserving = This->preserving;
1923 return S_OK;
1927 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1928 IXMLDOMDocument2 *iface,
1929 VARIANT_BOOL isPreserving )
1931 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1933 TRACE("(%p)->(%d)\n", This, isPreserving);
1934 This->preserving = isPreserving;
1935 return S_OK;
1939 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1940 IXMLDOMDocument2 *iface,
1941 VARIANT readyStateChangeSink )
1943 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1944 FIXME("%p\n", This);
1945 return E_NOTIMPL;
1949 static HRESULT WINAPI domdoc_put_onDataAvailable(
1950 IXMLDOMDocument2 *iface,
1951 VARIANT onDataAvailableSink )
1953 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1954 FIXME("%p\n", This);
1955 return E_NOTIMPL;
1958 static HRESULT WINAPI domdoc_put_onTransformNode(
1959 IXMLDOMDocument2 *iface,
1960 VARIANT onTransformNodeSink )
1962 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1963 FIXME("%p\n", This);
1964 return E_NOTIMPL;
1967 static HRESULT WINAPI domdoc_get_namespaces(
1968 IXMLDOMDocument2* iface,
1969 IXMLDOMSchemaCollection** schemaCollection )
1971 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1972 FIXME("(%p)->(%p)\n", This, schemaCollection);
1973 return E_NOTIMPL;
1976 static HRESULT WINAPI domdoc_get_schemas(
1977 IXMLDOMDocument2* iface,
1978 VARIANT* var1 )
1980 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1981 HRESULT hr = S_FALSE;
1982 IXMLDOMSchemaCollection *cur_schema = This->schema;
1984 TRACE("(%p)->(%p)\n", This, var1);
1986 VariantInit(var1); /* Test shows we don't call VariantClear here */
1987 V_VT(var1) = VT_NULL;
1989 if(cur_schema)
1991 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1992 if(SUCCEEDED(hr))
1993 V_VT(var1) = VT_DISPATCH;
1995 return hr;
1998 static HRESULT WINAPI domdoc_putref_schemas(
1999 IXMLDOMDocument2* iface,
2000 VARIANT var1)
2002 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2003 HRESULT hr = E_FAIL;
2004 IXMLDOMSchemaCollection *new_schema = NULL;
2006 FIXME("(%p): semi-stub\n", This);
2007 switch(V_VT(&var1))
2009 case VT_UNKNOWN:
2010 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2011 break;
2013 case VT_DISPATCH:
2014 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2015 break;
2017 case VT_NULL:
2018 case VT_EMPTY:
2019 hr = S_OK;
2020 break;
2022 default:
2023 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2026 if(SUCCEEDED(hr))
2028 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2029 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2032 return hr;
2035 static HRESULT WINAPI domdoc_validate(
2036 IXMLDOMDocument2* iface,
2037 IXMLDOMParseError** err)
2039 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2040 FIXME("(%p)->(%p)\n", This, err);
2041 return E_NOTIMPL;
2044 static HRESULT WINAPI domdoc_setProperty(
2045 IXMLDOMDocument2* iface,
2046 BSTR p,
2047 VARIANT var)
2049 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2051 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2053 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
2055 VARIANT varStr;
2056 HRESULT hr;
2057 BSTR bstr;
2059 V_VT(&varStr) = VT_EMPTY;
2060 if (V_VT(&var) != VT_BSTR)
2062 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2063 return hr;
2064 bstr = V_BSTR(&varStr);
2066 else
2067 bstr = V_BSTR(&var);
2069 hr = S_OK;
2070 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
2071 This->bUseXPath = TRUE;
2072 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
2073 This->bUseXPath = FALSE;
2074 else
2075 hr = E_FAIL;
2077 VariantClear(&varStr);
2078 return hr;
2081 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2082 return E_FAIL;
2085 static HRESULT WINAPI domdoc_getProperty(
2086 IXMLDOMDocument2* iface,
2087 BSTR p,
2088 VARIANT* var)
2090 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2092 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2094 if (var == NULL)
2095 return E_INVALIDARG;
2096 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
2098 V_VT(var) = VT_BSTR;
2099 if (This->bUseXPath)
2100 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
2101 else
2102 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
2103 return S_OK;
2106 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2107 return E_FAIL;
2110 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
2112 domdoc_QueryInterface,
2113 domdoc_AddRef,
2114 domdoc_Release,
2115 domdoc_GetTypeInfoCount,
2116 domdoc_GetTypeInfo,
2117 domdoc_GetIDsOfNames,
2118 domdoc_Invoke,
2119 domdoc_get_nodeName,
2120 domdoc_get_nodeValue,
2121 domdoc_put_nodeValue,
2122 domdoc_get_nodeType,
2123 domdoc_get_parentNode,
2124 domdoc_get_childNodes,
2125 domdoc_get_firstChild,
2126 domdoc_get_lastChild,
2127 domdoc_get_previousSibling,
2128 domdoc_get_nextSibling,
2129 domdoc_get_attributes,
2130 domdoc_insertBefore,
2131 domdoc_replaceChild,
2132 domdoc_removeChild,
2133 domdoc_appendChild,
2134 domdoc_hasChildNodes,
2135 domdoc_get_ownerDocument,
2136 domdoc_cloneNode,
2137 domdoc_get_nodeTypeString,
2138 domdoc_get_text,
2139 domdoc_put_text,
2140 domdoc_get_specified,
2141 domdoc_get_definition,
2142 domdoc_get_nodeTypedValue,
2143 domdoc_put_nodeTypedValue,
2144 domdoc_get_dataType,
2145 domdoc_put_dataType,
2146 domdoc_get_xml,
2147 domdoc_transformNode,
2148 domdoc_selectNodes,
2149 domdoc_selectSingleNode,
2150 domdoc_get_parsed,
2151 domdoc_get_namespaceURI,
2152 domdoc_get_prefix,
2153 domdoc_get_baseName,
2154 domdoc_transformNodeToObject,
2155 domdoc_get_doctype,
2156 domdoc_get_implementation,
2157 domdoc_get_documentElement,
2158 domdoc_put_documentElement,
2159 domdoc_createElement,
2160 domdoc_createDocumentFragment,
2161 domdoc_createTextNode,
2162 domdoc_createComment,
2163 domdoc_createCDATASection,
2164 domdoc_createProcessingInstruction,
2165 domdoc_createAttribute,
2166 domdoc_createEntityReference,
2167 domdoc_getElementsByTagName,
2168 domdoc_createNode,
2169 domdoc_nodeFromID,
2170 domdoc_load,
2171 domdoc_get_readyState,
2172 domdoc_get_parseError,
2173 domdoc_get_url,
2174 domdoc_get_async,
2175 domdoc_put_async,
2176 domdoc_abort,
2177 domdoc_loadXML,
2178 domdoc_save,
2179 domdoc_get_validateOnParse,
2180 domdoc_put_validateOnParse,
2181 domdoc_get_resolveExternals,
2182 domdoc_put_resolveExternals,
2183 domdoc_get_preserveWhiteSpace,
2184 domdoc_put_preserveWhiteSpace,
2185 domdoc_put_onReadyStateChange,
2186 domdoc_put_onDataAvailable,
2187 domdoc_put_onTransformNode,
2188 domdoc_get_namespaces,
2189 domdoc_get_schemas,
2190 domdoc_putref_schemas,
2191 domdoc_validate,
2192 domdoc_setProperty,
2193 domdoc_getProperty
2196 /* xmldoc implementation of IObjectWithSite */
2197 static HRESULT WINAPI
2198 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2200 domdoc *This = impl_from_IObjectWithSite(iface);
2201 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2204 static ULONG WINAPI
2205 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2207 domdoc *This = impl_from_IObjectWithSite(iface);
2208 return IXMLDocument_AddRef((IXMLDocument *)This);
2211 static ULONG WINAPI
2212 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2214 domdoc *This = impl_from_IObjectWithSite(iface);
2215 return IXMLDocument_Release((IXMLDocument *)This);
2218 static HRESULT WINAPI
2219 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2221 domdoc *This = impl_from_IObjectWithSite(iface);
2223 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2225 if ( !This->site )
2226 return E_FAIL;
2228 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2231 static HRESULT WINAPI
2232 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2234 domdoc *This = impl_from_IObjectWithSite(iface);
2236 TRACE("(%p)->(%p)\n", iface, punk);
2238 if(!punk)
2240 if(This->site)
2242 IUnknown_Release( This->site );
2243 This->site = NULL;
2246 return S_OK;
2249 IUnknown_AddRef( punk );
2251 if(This->site)
2252 IUnknown_Release( This->site );
2254 This->site = punk;
2256 return S_OK;
2259 static const IObjectWithSiteVtbl domdocObjectSite =
2261 xmldoc_ObjectWithSite_QueryInterface,
2262 xmldoc_ObjectWithSite_AddRef,
2263 xmldoc_ObjectWithSite_Release,
2264 xmldoc_SetSite,
2265 xmldoc_GetSite,
2268 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2270 domdoc *This = impl_from_IObjectSafety(iface);
2271 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2274 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2276 domdoc *This = impl_from_IObjectSafety(iface);
2277 return IXMLDocument_AddRef((IXMLDocument *)This);
2280 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2282 domdoc *This = impl_from_IObjectSafety(iface);
2283 return IXMLDocument_Release((IXMLDocument *)This);
2286 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2288 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2289 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2291 domdoc *This = impl_from_IObjectSafety(iface);
2293 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2295 if(!pdwSupportedOptions || !pdwEnabledOptions)
2296 return E_POINTER;
2298 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2299 *pdwEnabledOptions = This->safeopt;
2301 return S_OK;
2304 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2305 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2307 domdoc *This = impl_from_IObjectSafety(iface);
2308 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2310 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2311 return E_FAIL;
2313 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2314 return S_OK;
2317 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2318 xmldoc_Safety_QueryInterface,
2319 xmldoc_Safety_AddRef,
2320 xmldoc_Safety_Release,
2321 xmldoc_Safety_GetInterfaceSafetyOptions,
2322 xmldoc_Safety_SetInterfaceSafetyOptions
2326 static const tid_t domdoc_iface_tids[] = {
2327 IXMLDOMNode_tid,
2328 IXMLDOMDocument_tid,
2329 IXMLDOMDocument2_tid,
2332 static dispex_static_data_t domdoc_dispex = {
2333 NULL,
2334 IXMLDOMDocument2_tid,
2335 NULL,
2336 domdoc_iface_tids
2339 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2341 domdoc *doc;
2343 doc = heap_alloc( sizeof (*doc) );
2344 if( !doc )
2345 return E_OUTOFMEMORY;
2347 doc->lpVtbl = &domdoc_vtbl;
2348 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2349 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2350 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2351 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2352 doc->ref = 1;
2353 doc->async = VARIANT_TRUE;
2354 doc->validating = 0;
2355 doc->resolving = 0;
2356 doc->preserving = 0;
2357 doc->bUseXPath = FALSE;
2358 doc->error = S_OK;
2359 doc->schema = NULL;
2360 doc->stream = NULL;
2361 doc->site = NULL;
2362 doc->safeopt = 0;
2363 doc->bsc = NULL;
2365 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2367 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2369 TRACE("returning iface %p\n", *document);
2370 return S_OK;
2373 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2375 xmlDocPtr xmldoc;
2376 HRESULT hr;
2378 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2380 xmldoc = xmlNewDoc(NULL);
2381 if(!xmldoc)
2382 return E_OUTOFMEMORY;
2384 xmldoc->_private = create_priv();
2386 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2387 if(FAILED(hr))
2388 xmlFreeDoc(xmldoc);
2390 return hr;
2393 IUnknown* create_domdoc( xmlNodePtr document )
2395 HRESULT hr;
2396 LPVOID pObj = NULL;
2398 TRACE("(%p)\n", document);
2400 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2401 if (FAILED(hr))
2402 return NULL;
2404 return pObj;
2407 #else
2409 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2411 MESSAGE("This program tried to use a DOMDocument object, but\n"
2412 "libxml2 support was not present at compile time.\n");
2413 return E_NOTIMPL;
2416 #endif