wined3d: Pass a wined3d_state structure to use_vs().
[wine/multimedia.git] / dlls / msxml3 / domdoc.c
blob8f87a56e0d80d11709b6fbceeb5d80f4c2126baf
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 "msxml6.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 PropertySelectionLanguageW[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
62 static const WCHAR PropertySelectionNamespacesW[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
63 static const WCHAR PropertyProhibitDTDW[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
64 static const WCHAR PropValueXPathW[] = {'X','P','a','t','h',0};
65 static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r','n',0};
67 typedef struct _domdoc
69 xmlnode node;
70 const struct IXMLDOMDocument3Vtbl *lpVtbl;
71 const struct IPersistStreamInitVtbl *lpvtblIPersistStreamInit;
72 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
73 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
74 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
75 LONG ref;
76 VARIANT_BOOL async;
77 VARIANT_BOOL validating;
78 VARIANT_BOOL resolving;
79 VARIANT_BOOL preserving;
80 IXMLDOMSchemaCollection *schema;
81 bsc_t *bsc;
82 HRESULT error;
84 /* IPersistStream */
85 IStream *stream;
87 /* IObjectWithSite*/
88 IUnknown *site;
90 /* IObjectSafety */
91 DWORD safeopt;
92 } domdoc;
95 In native windows, the whole lifetime management of XMLDOMNodes is
96 managed automatically using reference counts. Wine emulates that by
97 maintaining a reference count to the document that is increased for
98 each IXMLDOMNode pointer passed out for this document. If all these
99 pointers are gone, the document is unreachable and gets freed, that
100 is, all nodes in the tree of the document get freed.
102 You are able to create nodes that are associated to a document (in
103 fact, in msxml's XMLDOM model, all nodes are associated to a document),
104 but not in the tree of that document, for example using the createFoo
105 functions from IXMLDOMDocument. These nodes do not get cleaned up
106 by libxml, so we have to do it ourselves.
108 To catch these nodes, a list of "orphan nodes" is introduced.
109 It contains pointers to all roots of node trees that are
110 associated with the document without being part of the document
111 tree. All nodes with parent==NULL (except for the document root nodes)
112 should be in the orphan node list of their document. All orphan nodes
113 get freed together with the document itself.
116 typedef struct _xmldoc_priv {
117 LONG refs;
118 struct list orphans;
119 BOOL XPath;
120 } xmldoc_priv;
122 typedef struct _orphan_entry {
123 struct list entry;
124 xmlNode * node;
125 } orphan_entry;
127 static inline xmldoc_priv * priv_from_xmlDocPtr(const xmlDocPtr doc)
129 return doc->_private;
132 static inline BOOL is_xpathmode(const xmlDocPtr doc)
134 return priv_from_xmlDocPtr(doc)->XPath;
137 static inline void set_xpathmode(const xmlDocPtr doc)
139 priv_from_xmlDocPtr(doc)->XPath = TRUE;
142 static inline void reset_xpathmode(const xmlDocPtr doc)
144 priv_from_xmlDocPtr(doc)->XPath = FALSE;
147 static xmldoc_priv * create_priv(void)
149 xmldoc_priv *priv;
150 priv = heap_alloc( sizeof (*priv) );
152 if (priv)
154 priv->refs = 0;
155 priv->XPath = FALSE;
156 list_init( &priv->orphans );
159 return priv;
162 /* links a "<?xml" node as a first child */
163 void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
165 assert(doc != NULL);
166 if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
169 /* unlinks a first "<?xml" child if it was created */
170 xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
172 xmlNodePtr node;
174 assert(doc != NULL);
176 if (doc->standalone != -1)
178 node = doc->children;
179 xmlUnlinkNode( node );
181 else
182 node = NULL;
184 return node;
187 static xmlDocPtr doparse( char *ptr, int len, const char *encoding )
189 xmlDocPtr doc;
191 #ifdef HAVE_XMLREADMEMORY
193 * use xmlReadMemory if possible so we can suppress
194 * writing errors to stderr
196 doc = xmlReadMemory( ptr, len, NULL, encoding,
197 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
198 #else
199 doc = xmlParseMemory( ptr, len );
200 #endif
202 /* create first child as a <?xml...?> */
203 if (doc && doc->standalone != -1)
205 xmlNodePtr node;
206 char buff[30];
207 xmlChar *xmlbuff = (xmlChar*)buff;
209 node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
211 /* version attribute can't be omitted */
212 sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
213 xmlNodeAddContent( node, xmlbuff );
215 if (doc->encoding)
217 sprintf(buff, " encoding=\"%s\"", doc->encoding);
218 xmlNodeAddContent( node, xmlbuff );
221 if (doc->standalone != -2)
223 sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
224 xmlNodeAddContent( node, xmlbuff );
227 xmldoc_link_xmldecl( doc, node );
230 return doc;
233 LONG xmldoc_add_ref(xmlDocPtr doc)
235 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
236 TRACE("(%p)->(%d)\n", doc, ref);
237 return ref;
240 LONG xmldoc_release(xmlDocPtr doc)
242 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
243 LONG ref = InterlockedDecrement(&priv->refs);
244 TRACE("(%p)->(%d)\n", doc, ref);
245 if(ref == 0)
247 orphan_entry *orphan, *orphan2;
248 TRACE("freeing docptr %p\n", doc);
250 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
252 xmlFreeNode( orphan->node );
253 heap_free( orphan );
255 heap_free(doc->_private);
257 xmlFreeDoc(doc);
260 return ref;
263 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
265 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
266 orphan_entry *entry;
268 entry = heap_alloc( sizeof (*entry) );
269 if(!entry)
270 return E_OUTOFMEMORY;
272 entry->node = node;
273 list_add_head( &priv->orphans, &entry->entry );
274 return S_OK;
277 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
279 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
280 orphan_entry *entry, *entry2;
282 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
284 if( entry->node == node )
286 list_remove( &entry->entry );
287 heap_free( entry );
288 return S_OK;
292 return S_FALSE;
295 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
297 if(node->node)
298 xmldoc_release(node->node->doc);
300 node->node = (xmlNodePtr) xml;
301 if(node->node)
302 xmldoc_add_ref(node->node->doc);
304 return S_OK;
307 static inline domdoc *impl_from_IXMLDOMDocument3( IXMLDOMDocument3 *iface )
309 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
312 static inline xmlDocPtr get_doc( domdoc *This )
314 return (xmlDocPtr)This->node.node;
317 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
319 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
322 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
324 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
327 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
329 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
332 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
334 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
337 /************************************************************************
338 * domdoc implementation of IPersistStream.
340 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
341 IPersistStreamInit *iface, REFIID riid, void **ppvObj)
343 domdoc *this = impl_from_IPersistStreamInit(iface);
344 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
347 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
348 IPersistStreamInit *iface)
350 domdoc *this = impl_from_IPersistStreamInit(iface);
351 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
354 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
355 IPersistStreamInit *iface)
357 domdoc *this = impl_from_IPersistStreamInit(iface);
358 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
361 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
362 IPersistStreamInit *iface, CLSID *classid)
364 TRACE("(%p,%p): stub!\n", iface, classid);
366 if(!classid)
367 return E_POINTER;
369 *classid = CLSID_DOMDocument2;
371 return S_OK;
374 static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
375 IPersistStreamInit *iface)
377 domdoc *This = impl_from_IPersistStreamInit(iface);
378 FIXME("(%p): stub!\n", This);
379 return S_FALSE;
382 static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
383 IPersistStreamInit *iface, LPSTREAM pStm)
385 domdoc *This = impl_from_IPersistStreamInit(iface);
386 HRESULT hr;
387 HGLOBAL hglobal;
388 DWORD read, written, len;
389 BYTE buf[4096];
390 char *ptr;
391 xmlDocPtr xmldoc = NULL;
393 TRACE("(%p)->(%p)\n", This, pStm);
395 if (!pStm)
396 return E_INVALIDARG;
398 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
399 if (FAILED(hr))
400 return hr;
404 IStream_Read(pStm, buf, sizeof(buf), &read);
405 hr = IStream_Write(This->stream, buf, read, &written);
406 } while(SUCCEEDED(hr) && written != 0 && read != 0);
408 if (FAILED(hr))
410 ERR("Failed to copy stream\n");
411 return hr;
414 hr = GetHGlobalFromStream(This->stream, &hglobal);
415 if (FAILED(hr))
416 return hr;
418 len = GlobalSize(hglobal);
419 ptr = GlobalLock(hglobal);
420 if (len != 0)
421 xmldoc = doparse(ptr, len, NULL);
422 GlobalUnlock(hglobal);
424 if (!xmldoc)
426 ERR("Failed to parse xml\n");
427 return E_FAIL;
430 xmldoc->_private = create_priv();
432 return attach_xmldoc( &This->node, xmldoc );
435 static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
436 IPersistStreamInit *iface, IStream *stream, BOOL clr_dirty)
438 domdoc *This = impl_from_IPersistStreamInit(iface);
439 BSTR xmlString;
440 HRESULT hr;
442 TRACE("(%p)->(%p %d)\n", This, stream, clr_dirty);
444 hr = IXMLDOMDocument3_get_xml( (IXMLDOMDocument3*)&This->lpVtbl, &xmlString );
445 if(hr == S_OK)
447 DWORD len = SysStringLen(xmlString) * sizeof(WCHAR);
449 hr = IStream_Write( stream, xmlString, len, NULL );
450 SysFreeString(xmlString);
453 TRACE("ret 0x%08x\n", hr);
455 return hr;
458 static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
459 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
461 domdoc *This = impl_from_IPersistStreamInit(iface);
462 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
463 return E_NOTIMPL;
466 static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
467 IPersistStreamInit *iface)
469 domdoc *This = impl_from_IPersistStreamInit(iface);
470 TRACE("(%p)\n", This);
471 return S_OK;
474 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
476 domdoc_IPersistStreamInit_QueryInterface,
477 domdoc_IPersistStreamInit_AddRef,
478 domdoc_IPersistStreamInit_Release,
479 domdoc_IPersistStreamInit_GetClassID,
480 domdoc_IPersistStreamInit_IsDirty,
481 domdoc_IPersistStreamInit_Load,
482 domdoc_IPersistStreamInit_Save,
483 domdoc_IPersistStreamInit_GetSizeMax,
484 domdoc_IPersistStreamInit_InitNew
487 /* ISupportErrorInfo interface */
488 static HRESULT WINAPI support_error_QueryInterface(
489 ISupportErrorInfo *iface,
490 REFIID riid, void** ppvObj )
492 domdoc *This = impl_from_ISupportErrorInfo(iface);
493 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3 *)This, riid, ppvObj);
496 static ULONG WINAPI support_error_AddRef(
497 ISupportErrorInfo *iface )
499 domdoc *This = impl_from_ISupportErrorInfo(iface);
500 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3 *)This);
503 static ULONG WINAPI support_error_Release(
504 ISupportErrorInfo *iface )
506 domdoc *This = impl_from_ISupportErrorInfo(iface);
507 return IXMLDOMDocument3_Release((IXMLDOMDocument3 *)This);
510 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
511 ISupportErrorInfo *iface,
512 REFIID riid )
514 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
515 return S_FALSE;
518 static const struct ISupportErrorInfoVtbl support_error_vtbl =
520 support_error_QueryInterface,
521 support_error_AddRef,
522 support_error_Release,
523 support_error_InterfaceSupportsErrorInfo
526 /* IXMLDOMDocument2 interface */
527 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID riid, void** ppvObject )
529 domdoc *This = impl_from_IXMLDOMDocument3( iface );
531 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
533 *ppvObject = NULL;
535 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
536 IsEqualGUID( riid, &IID_IDispatch ) ||
537 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
538 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
539 IsEqualGUID( riid, &IID_IXMLDOMDocument2 )||
540 IsEqualGUID( riid, &IID_IXMLDOMDocument3 ))
542 *ppvObject = iface;
544 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
545 IsEqualGUID(&IID_IPersistStreamInit, riid))
547 *ppvObject = &(This->lpvtblIPersistStreamInit);
549 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
551 *ppvObject = &(This->lpvtblIObjectWithSite);
553 else if (IsEqualGUID(&IID_IObjectSafety, riid))
555 *ppvObject = &(This->lpvtblIObjectSafety);
557 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
559 *ppvObject = &This->lpvtblISupportErrorInfo;
561 else if(node_query_interface(&This->node, riid, ppvObject))
563 return *ppvObject ? S_OK : E_NOINTERFACE;
565 else if(IsEqualGUID(&IID_IRunnableObject, riid))
567 TRACE("IID_IRunnableObject not supported returning NULL\n");
568 return E_NOINTERFACE;
570 else
572 FIXME("interface %s not implemented\n", debugstr_guid(riid));
573 return E_NOINTERFACE;
576 IUnknown_AddRef((IUnknown*)*ppvObject);
578 return S_OK;
582 static ULONG WINAPI domdoc_AddRef(
583 IXMLDOMDocument3 *iface )
585 domdoc *This = impl_from_IXMLDOMDocument3( iface );
586 TRACE("%p\n", This );
587 return InterlockedIncrement( &This->ref );
591 static ULONG WINAPI domdoc_Release(
592 IXMLDOMDocument3 *iface )
594 domdoc *This = impl_from_IXMLDOMDocument3( iface );
595 LONG ref;
597 TRACE("%p\n", This );
599 ref = InterlockedDecrement( &This->ref );
600 if ( ref == 0 )
602 if(This->bsc)
603 detach_bsc(This->bsc);
605 if (This->site)
606 IUnknown_Release( This->site );
607 destroy_xmlnode(&This->node);
608 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
609 if (This->stream) IStream_Release(This->stream);
610 HeapFree( GetProcessHeap(), 0, This );
613 return ref;
616 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument3 *iface, UINT* pctinfo )
618 domdoc *This = impl_from_IXMLDOMDocument3( iface );
620 TRACE("(%p)->(%p)\n", This, pctinfo);
622 *pctinfo = 1;
624 return S_OK;
627 static HRESULT WINAPI domdoc_GetTypeInfo(
628 IXMLDOMDocument3 *iface,
629 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
631 domdoc *This = impl_from_IXMLDOMDocument3( iface );
632 HRESULT hr;
634 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
636 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
638 return hr;
641 static HRESULT WINAPI domdoc_GetIDsOfNames(
642 IXMLDOMDocument3 *iface,
643 REFIID riid,
644 LPOLESTR* rgszNames,
645 UINT cNames,
646 LCID lcid,
647 DISPID* rgDispId)
649 domdoc *This = impl_from_IXMLDOMDocument3( iface );
650 ITypeInfo *typeinfo;
651 HRESULT hr;
653 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
654 lcid, rgDispId);
656 if(!rgszNames || cNames == 0 || !rgDispId)
657 return E_INVALIDARG;
659 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
660 if(SUCCEEDED(hr))
662 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
663 ITypeInfo_Release(typeinfo);
666 return hr;
670 static HRESULT WINAPI domdoc_Invoke(
671 IXMLDOMDocument3 *iface,
672 DISPID dispIdMember,
673 REFIID riid,
674 LCID lcid,
675 WORD wFlags,
676 DISPPARAMS* pDispParams,
677 VARIANT* pVarResult,
678 EXCEPINFO* pExcepInfo,
679 UINT* puArgErr)
681 domdoc *This = impl_from_IXMLDOMDocument3( iface );
682 ITypeInfo *typeinfo;
683 HRESULT hr;
685 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
686 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
688 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
689 if(SUCCEEDED(hr))
691 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
692 pVarResult, pExcepInfo, puArgErr);
693 ITypeInfo_Release(typeinfo);
696 return hr;
700 static HRESULT WINAPI domdoc_get_nodeName(
701 IXMLDOMDocument3 *iface,
702 BSTR* name )
704 domdoc *This = impl_from_IXMLDOMDocument3( iface );
706 static const WCHAR documentW[] = {'#','d','o','c','u','m','e','n','t',0};
708 TRACE("(%p)->(%p)\n", This, name);
710 return return_bstr(documentW, name);
714 static HRESULT WINAPI domdoc_get_nodeValue(
715 IXMLDOMDocument3 *iface,
716 VARIANT* value )
718 domdoc *This = impl_from_IXMLDOMDocument3( iface );
720 TRACE("(%p)->(%p)\n", This, value);
722 if(!value)
723 return E_INVALIDARG;
725 V_VT(value) = VT_NULL;
726 V_BSTR(value) = NULL; /* tests show that we should do this */
727 return S_FALSE;
731 static HRESULT WINAPI domdoc_put_nodeValue(
732 IXMLDOMDocument3 *iface,
733 VARIANT value)
735 domdoc *This = impl_from_IXMLDOMDocument3( iface );
736 FIXME("(%p)->(v%d)\n", This, V_VT(&value));
737 return E_FAIL;
741 static HRESULT WINAPI domdoc_get_nodeType(
742 IXMLDOMDocument3 *iface,
743 DOMNodeType* type )
745 domdoc *This = impl_from_IXMLDOMDocument3( iface );
747 TRACE("(%p)->(%p)\n", This, type);
749 *type = NODE_DOCUMENT;
750 return S_OK;
754 static HRESULT WINAPI domdoc_get_parentNode(
755 IXMLDOMDocument3 *iface,
756 IXMLDOMNode** parent )
758 domdoc *This = impl_from_IXMLDOMDocument3( iface );
760 TRACE("(%p)->(%p)\n", This, parent);
762 return node_get_parent(&This->node, parent);
766 static HRESULT WINAPI domdoc_get_childNodes(
767 IXMLDOMDocument3 *iface,
768 IXMLDOMNodeList** childList )
770 domdoc *This = impl_from_IXMLDOMDocument3( iface );
772 TRACE("(%p)->(%p)\n", This, childList);
774 return node_get_child_nodes(&This->node, childList);
778 static HRESULT WINAPI domdoc_get_firstChild(
779 IXMLDOMDocument3 *iface,
780 IXMLDOMNode** firstChild )
782 domdoc *This = impl_from_IXMLDOMDocument3( iface );
784 TRACE("(%p)->(%p)\n", This, firstChild);
786 return node_get_first_child(&This->node, firstChild);
790 static HRESULT WINAPI domdoc_get_lastChild(
791 IXMLDOMDocument3 *iface,
792 IXMLDOMNode** lastChild )
794 domdoc *This = impl_from_IXMLDOMDocument3( iface );
796 TRACE("(%p)->(%p)\n", This, lastChild);
798 return node_get_last_child(&This->node, lastChild);
802 static HRESULT WINAPI domdoc_get_previousSibling(
803 IXMLDOMDocument3 *iface,
804 IXMLDOMNode** previousSibling )
806 domdoc *This = impl_from_IXMLDOMDocument3( iface );
808 TRACE("(%p)->(%p)\n", This, previousSibling);
810 return return_null_node(previousSibling);
814 static HRESULT WINAPI domdoc_get_nextSibling(
815 IXMLDOMDocument3 *iface,
816 IXMLDOMNode** nextSibling )
818 domdoc *This = impl_from_IXMLDOMDocument3( iface );
820 TRACE("(%p)->(%p)\n", This, nextSibling);
822 return return_null_node(nextSibling);
826 static HRESULT WINAPI domdoc_get_attributes(
827 IXMLDOMDocument3 *iface,
828 IXMLDOMNamedNodeMap** attributeMap )
830 domdoc *This = impl_from_IXMLDOMDocument3( iface );
832 TRACE("(%p)->(%p)\n", This, attributeMap);
834 return return_null_ptr((void**)attributeMap);
838 static HRESULT WINAPI domdoc_insertBefore(
839 IXMLDOMDocument3 *iface,
840 IXMLDOMNode* newChild,
841 VARIANT refChild,
842 IXMLDOMNode** outNewChild )
844 domdoc *This = impl_from_IXMLDOMDocument3( iface );
846 TRACE("(%p)->(%p x%d %p)\n", This, newChild, V_VT(&refChild), outNewChild);
848 return node_insert_before(&This->node, newChild, &refChild, outNewChild);
852 static HRESULT WINAPI domdoc_replaceChild(
853 IXMLDOMDocument3 *iface,
854 IXMLDOMNode* newChild,
855 IXMLDOMNode* oldChild,
856 IXMLDOMNode** outOldChild)
858 domdoc *This = impl_from_IXMLDOMDocument3( iface );
859 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
863 static HRESULT WINAPI domdoc_removeChild(
864 IXMLDOMDocument3 *iface,
865 IXMLDOMNode* childNode,
866 IXMLDOMNode** oldChild)
868 domdoc *This = impl_from_IXMLDOMDocument3( iface );
869 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
873 static HRESULT WINAPI domdoc_appendChild(
874 IXMLDOMDocument3 *iface,
875 IXMLDOMNode* newChild,
876 IXMLDOMNode** outNewChild)
878 domdoc *This = impl_from_IXMLDOMDocument3( iface );
879 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
883 static HRESULT WINAPI domdoc_hasChildNodes(
884 IXMLDOMDocument3 *iface,
885 VARIANT_BOOL* hasChild)
887 domdoc *This = impl_from_IXMLDOMDocument3( iface );
888 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
892 static HRESULT WINAPI domdoc_get_ownerDocument(
893 IXMLDOMDocument3 *iface,
894 IXMLDOMDocument** DOMDocument)
896 domdoc *This = impl_from_IXMLDOMDocument3( iface );
897 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
901 static HRESULT WINAPI domdoc_cloneNode(
902 IXMLDOMDocument3 *iface,
903 VARIANT_BOOL deep,
904 IXMLDOMNode** cloneRoot)
906 domdoc *This = impl_from_IXMLDOMDocument3( iface );
907 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
911 static HRESULT WINAPI domdoc_get_nodeTypeString(
912 IXMLDOMDocument3 *iface,
913 BSTR* nodeType )
915 domdoc *This = impl_from_IXMLDOMDocument3( iface );
916 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
920 static HRESULT WINAPI domdoc_get_text(
921 IXMLDOMDocument3 *iface,
922 BSTR* text )
924 domdoc *This = impl_from_IXMLDOMDocument3( iface );
925 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
929 static HRESULT WINAPI domdoc_put_text(
930 IXMLDOMDocument3 *iface,
931 BSTR text )
933 domdoc *This = impl_from_IXMLDOMDocument3( iface );
934 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
938 static HRESULT WINAPI domdoc_get_specified(
939 IXMLDOMDocument3 *iface,
940 VARIANT_BOOL* isSpecified )
942 domdoc *This = impl_from_IXMLDOMDocument3( iface );
943 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
947 static HRESULT WINAPI domdoc_get_definition(
948 IXMLDOMDocument3 *iface,
949 IXMLDOMNode** definitionNode )
951 domdoc *This = impl_from_IXMLDOMDocument3( iface );
952 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
956 static HRESULT WINAPI domdoc_get_nodeTypedValue(
957 IXMLDOMDocument3 *iface,
958 VARIANT* typedValue )
960 domdoc *This = impl_from_IXMLDOMDocument3( iface );
961 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
964 static HRESULT WINAPI domdoc_put_nodeTypedValue(
965 IXMLDOMDocument3 *iface,
966 VARIANT typedValue )
968 domdoc *This = impl_from_IXMLDOMDocument3( iface );
969 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
973 static HRESULT WINAPI domdoc_get_dataType(
974 IXMLDOMDocument3 *iface,
975 VARIANT* dataTypeName )
977 domdoc *This = impl_from_IXMLDOMDocument3( iface );
978 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
982 static HRESULT WINAPI domdoc_put_dataType(
983 IXMLDOMDocument3 *iface,
984 BSTR dataTypeName )
986 domdoc *This = impl_from_IXMLDOMDocument3( iface );
987 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
991 static HRESULT WINAPI domdoc_get_xml(
992 IXMLDOMDocument3 *iface,
993 BSTR* xmlString )
995 domdoc *This = impl_from_IXMLDOMDocument3( iface );
996 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
1000 static HRESULT WINAPI domdoc_transformNode(
1001 IXMLDOMDocument3 *iface,
1002 IXMLDOMNode* styleSheet,
1003 BSTR* xmlString )
1005 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1006 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
1010 static HRESULT WINAPI domdoc_selectNodes(
1011 IXMLDOMDocument3 *iface,
1012 BSTR queryString,
1013 IXMLDOMNodeList** resultList )
1015 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1016 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
1020 static HRESULT WINAPI domdoc_selectSingleNode(
1021 IXMLDOMDocument3 *iface,
1022 BSTR queryString,
1023 IXMLDOMNode** resultNode )
1025 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1026 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
1030 static HRESULT WINAPI domdoc_get_parsed(
1031 IXMLDOMDocument3 *iface,
1032 VARIANT_BOOL* isParsed )
1034 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1035 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
1039 static HRESULT WINAPI domdoc_get_namespaceURI(
1040 IXMLDOMDocument3 *iface,
1041 BSTR* namespaceURI )
1043 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1044 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
1048 static HRESULT WINAPI domdoc_get_prefix(
1049 IXMLDOMDocument3 *iface,
1050 BSTR* prefixString )
1052 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1053 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1057 static HRESULT WINAPI domdoc_get_baseName(
1058 IXMLDOMDocument3 *iface,
1059 BSTR* nameString )
1061 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1062 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1066 static HRESULT WINAPI domdoc_transformNodeToObject(
1067 IXMLDOMDocument3 *iface,
1068 IXMLDOMNode* stylesheet,
1069 VARIANT outputObject)
1071 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1072 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1076 static HRESULT WINAPI domdoc_get_doctype(
1077 IXMLDOMDocument3 *iface,
1078 IXMLDOMDocumentType** documentType )
1080 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1081 FIXME("(%p)\n", This);
1082 return E_NOTIMPL;
1086 static HRESULT WINAPI domdoc_get_implementation(
1087 IXMLDOMDocument3 *iface,
1088 IXMLDOMImplementation** impl )
1090 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1092 TRACE("(%p)->(%p)\n", This, impl);
1094 if(!impl)
1095 return E_INVALIDARG;
1097 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1099 return S_OK;
1102 static HRESULT WINAPI domdoc_get_documentElement(
1103 IXMLDOMDocument3 *iface,
1104 IXMLDOMElement** DOMElement )
1106 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1107 IXMLDOMNode *element_node;
1108 xmlNodePtr root;
1109 HRESULT hr;
1111 TRACE("(%p)->(%p)\n", This, DOMElement);
1113 if(!DOMElement)
1114 return E_INVALIDARG;
1116 *DOMElement = NULL;
1118 root = xmlDocGetRootElement( get_doc(This) );
1119 if ( !root )
1120 return S_FALSE;
1122 element_node = create_node( root );
1123 if(!element_node) return S_FALSE;
1125 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement);
1126 IXMLDOMNode_Release(element_node);
1128 return hr;
1132 static HRESULT WINAPI domdoc_put_documentElement(
1133 IXMLDOMDocument3 *iface,
1134 IXMLDOMElement* DOMElement )
1136 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1137 IXMLDOMNode *elementNode;
1138 xmlNodePtr oldRoot;
1139 xmlnode *xmlNode;
1140 HRESULT hr;
1142 TRACE("(%p)->(%p)\n", This, DOMElement);
1144 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1145 if(FAILED(hr))
1146 return hr;
1148 xmlNode = get_node_obj( elementNode );
1149 if(!xmlNode) {
1150 FIXME("elementNode is not our object\n");
1151 return E_FAIL;
1154 if(!xmlNode->node->parent)
1155 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1156 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1158 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1159 IXMLDOMNode_Release( elementNode );
1161 if(oldRoot)
1162 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1164 return S_OK;
1168 static HRESULT WINAPI domdoc_createElement(
1169 IXMLDOMDocument3 *iface,
1170 BSTR tagname,
1171 IXMLDOMElement** element )
1173 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1174 IXMLDOMNode *node;
1175 VARIANT type;
1176 HRESULT hr;
1178 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1180 if (!element || !tagname) return E_INVALIDARG;
1182 V_VT(&type) = VT_I1;
1183 V_I1(&type) = NODE_ELEMENT;
1185 hr = IXMLDOMDocument3_createNode(iface, type, tagname, NULL, &node);
1186 if (hr == S_OK)
1188 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1189 IXMLDOMNode_Release(node);
1192 return hr;
1196 static HRESULT WINAPI domdoc_createDocumentFragment(
1197 IXMLDOMDocument3 *iface,
1198 IXMLDOMDocumentFragment** frag )
1200 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1201 IXMLDOMNode *node;
1202 VARIANT type;
1203 HRESULT hr;
1205 TRACE("(%p)->(%p)\n", This, frag);
1207 if (!frag) return E_INVALIDARG;
1209 *frag = NULL;
1211 V_VT(&type) = VT_I1;
1212 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1214 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1215 if (hr == S_OK)
1217 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1218 IXMLDOMNode_Release(node);
1221 return hr;
1225 static HRESULT WINAPI domdoc_createTextNode(
1226 IXMLDOMDocument3 *iface,
1227 BSTR data,
1228 IXMLDOMText** text )
1230 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1231 IXMLDOMNode *node;
1232 VARIANT type;
1233 HRESULT hr;
1235 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1237 if (!text) return E_INVALIDARG;
1239 *text = NULL;
1241 V_VT(&type) = VT_I1;
1242 V_I1(&type) = NODE_TEXT;
1244 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1245 if (hr == S_OK)
1247 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1248 IXMLDOMNode_Release(node);
1249 hr = IXMLDOMText_put_data(*text, data);
1252 return hr;
1256 static HRESULT WINAPI domdoc_createComment(
1257 IXMLDOMDocument3 *iface,
1258 BSTR data,
1259 IXMLDOMComment** comment )
1261 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1262 VARIANT type;
1263 HRESULT hr;
1264 IXMLDOMNode *node;
1266 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1268 if (!comment) return E_INVALIDARG;
1270 *comment = NULL;
1272 V_VT(&type) = VT_I1;
1273 V_I1(&type) = NODE_COMMENT;
1275 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1276 if (hr == S_OK)
1278 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1279 IXMLDOMNode_Release(node);
1280 hr = IXMLDOMComment_put_data(*comment, data);
1283 return hr;
1287 static HRESULT WINAPI domdoc_createCDATASection(
1288 IXMLDOMDocument3 *iface,
1289 BSTR data,
1290 IXMLDOMCDATASection** cdata )
1292 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1293 IXMLDOMNode *node;
1294 VARIANT type;
1295 HRESULT hr;
1297 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1299 if (!cdata) return E_INVALIDARG;
1301 *cdata = NULL;
1303 V_VT(&type) = VT_I1;
1304 V_I1(&type) = NODE_CDATA_SECTION;
1306 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1307 if (hr == S_OK)
1309 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1310 IXMLDOMNode_Release(node);
1311 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1314 return hr;
1318 static HRESULT WINAPI domdoc_createProcessingInstruction(
1319 IXMLDOMDocument3 *iface,
1320 BSTR target,
1321 BSTR data,
1322 IXMLDOMProcessingInstruction** pi )
1324 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1325 IXMLDOMNode *node;
1326 VARIANT type;
1327 HRESULT hr;
1329 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1331 if (!pi) return E_INVALIDARG;
1333 *pi = NULL;
1335 V_VT(&type) = VT_I1;
1336 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1338 hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node);
1339 if (hr == S_OK)
1341 VARIANT v_data;
1342 xmlnode *node_obj;
1344 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1345 node_obj = get_node_obj(node);
1346 V_VT(&v_data) = VT_BSTR;
1347 V_BSTR(&v_data) = data;
1349 hr = node_put_value(node_obj, &v_data);
1351 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1352 IXMLDOMNode_Release(node);
1355 return hr;
1359 static HRESULT WINAPI domdoc_createAttribute(
1360 IXMLDOMDocument3 *iface,
1361 BSTR name,
1362 IXMLDOMAttribute** attribute )
1364 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1365 IXMLDOMNode *node;
1366 VARIANT type;
1367 HRESULT hr;
1369 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1371 if (!attribute || !name) return E_INVALIDARG;
1373 V_VT(&type) = VT_I1;
1374 V_I1(&type) = NODE_ATTRIBUTE;
1376 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1377 if (hr == S_OK)
1379 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1380 IXMLDOMNode_Release(node);
1383 return hr;
1387 static HRESULT WINAPI domdoc_createEntityReference(
1388 IXMLDOMDocument3 *iface,
1389 BSTR name,
1390 IXMLDOMEntityReference** entityref )
1392 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1393 IXMLDOMNode *node;
1394 VARIANT type;
1395 HRESULT hr;
1397 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1399 if (!entityref) return E_INVALIDARG;
1401 *entityref = NULL;
1403 V_VT(&type) = VT_I1;
1404 V_I1(&type) = NODE_ENTITY_REFERENCE;
1406 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1407 if (hr == S_OK)
1409 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1410 IXMLDOMNode_Release(node);
1413 return hr;
1417 static HRESULT WINAPI domdoc_getElementsByTagName(
1418 IXMLDOMDocument3 *iface,
1419 BSTR tagName,
1420 IXMLDOMNodeList** resultList )
1422 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1423 HRESULT hr;
1425 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1427 if (!tagName || !resultList) return E_INVALIDARG;
1429 if (tagName[0] == '*' && tagName[1] == 0)
1431 static const WCHAR formatallW[] = {'/','/','*',0};
1432 hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList);
1434 else
1436 static const WCHAR xpathformat[] =
1437 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1438 static const WCHAR closeW[] = { '\'',']',0 };
1440 LPWSTR pattern;
1441 WCHAR *ptr;
1442 INT length;
1444 length = lstrlenW(tagName);
1446 /* without two WCHARs from format specifier */
1447 ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
1449 memcpy(ptr, xpathformat, sizeof(xpathformat));
1450 ptr += sizeof(xpathformat)/sizeof(WCHAR);
1451 memcpy(ptr, tagName, length*sizeof(WCHAR));
1452 ptr += length;
1453 memcpy(ptr, closeW, sizeof(closeW));
1455 hr = queryresult_create((xmlNodePtr)get_doc(This), pattern, resultList);
1456 heap_free(pattern);
1459 return hr;
1462 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1464 VARIANT tmp;
1465 HRESULT hr;
1467 VariantInit(&tmp);
1468 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1469 if(FAILED(hr))
1470 return E_INVALIDARG;
1472 *type = V_I4(&tmp);
1474 return S_OK;
1477 static HRESULT WINAPI domdoc_createNode(
1478 IXMLDOMDocument3 *iface,
1479 VARIANT Type,
1480 BSTR name,
1481 BSTR namespaceURI,
1482 IXMLDOMNode** node )
1484 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1485 DOMNodeType node_type;
1486 xmlNodePtr xmlnode;
1487 xmlChar *xml_name, *href;
1488 HRESULT hr;
1490 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1492 if(!node) return E_INVALIDARG;
1494 hr = get_node_type(Type, &node_type);
1495 if(FAILED(hr)) return hr;
1497 if(namespaceURI && namespaceURI[0] && node_type != NODE_ELEMENT)
1498 FIXME("nodes with namespaces currently not supported.\n");
1500 TRACE("node_type %d\n", node_type);
1502 /* exit earlier for types that need name */
1503 switch(node_type)
1505 case NODE_ELEMENT:
1506 case NODE_ATTRIBUTE:
1507 case NODE_ENTITY_REFERENCE:
1508 case NODE_PROCESSING_INSTRUCTION:
1509 if (!name || *name == 0) return E_FAIL;
1510 default:
1511 break;
1514 xml_name = xmlChar_from_wchar(name);
1515 /* prevent empty href to be allocated */
1516 href = namespaceURI ? xmlChar_from_wchar(namespaceURI) : NULL;
1518 switch(node_type)
1520 case NODE_ELEMENT:
1522 xmlChar *local, *prefix;
1524 local = xmlSplitQName2(xml_name, &prefix);
1526 xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL);
1528 /* allow to create default namespace xmlns= */
1529 if (local || (href && *href))
1531 xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix);
1532 xmlSetNs(xmlnode, ns);
1535 xmlFree(local);
1536 xmlFree(prefix);
1538 break;
1540 case NODE_ATTRIBUTE:
1541 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1542 break;
1543 case NODE_TEXT:
1544 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1545 break;
1546 case NODE_CDATA_SECTION:
1547 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1548 break;
1549 case NODE_ENTITY_REFERENCE:
1550 xmlnode = xmlNewReference(get_doc(This), xml_name);
1551 break;
1552 case NODE_PROCESSING_INSTRUCTION:
1553 #ifdef HAVE_XMLNEWDOCPI
1554 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1555 #else
1556 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1557 xmlnode = NULL;
1558 #endif
1559 break;
1560 case NODE_COMMENT:
1561 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1562 break;
1563 case NODE_DOCUMENT_FRAGMENT:
1564 xmlnode = xmlNewDocFragment(get_doc(This));
1565 break;
1566 /* unsupported types */
1567 case NODE_DOCUMENT:
1568 case NODE_DOCUMENT_TYPE:
1569 case NODE_ENTITY:
1570 case NODE_NOTATION:
1571 heap_free(xml_name);
1572 return E_INVALIDARG;
1573 default:
1574 FIXME("unhandled node type %d\n", node_type);
1575 xmlnode = NULL;
1576 break;
1579 *node = create_node(xmlnode);
1580 heap_free(xml_name);
1581 heap_free(href);
1583 if(*node)
1585 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1586 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1587 return S_OK;
1590 return E_FAIL;
1593 static HRESULT WINAPI domdoc_nodeFromID(
1594 IXMLDOMDocument3 *iface,
1595 BSTR idString,
1596 IXMLDOMNode** node )
1598 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1599 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1600 return E_NOTIMPL;
1603 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1605 domdoc *This = obj;
1606 xmlDocPtr xmldoc;
1608 xmldoc = doparse( ptr, len, NULL );
1609 if(xmldoc) {
1610 xmldoc->_private = create_priv();
1611 return attach_xmldoc(&This->node, xmldoc);
1614 return S_OK;
1617 static HRESULT doread( domdoc *This, LPWSTR filename )
1619 bsc_t *bsc;
1620 HRESULT hr;
1622 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1623 if(FAILED(hr))
1624 return hr;
1626 if(This->bsc)
1627 detach_bsc(This->bsc);
1629 This->bsc = bsc;
1630 return S_OK;
1633 static HRESULT WINAPI domdoc_load(
1634 IXMLDOMDocument3 *iface,
1635 VARIANT xmlSource,
1636 VARIANT_BOOL* isSuccessful )
1638 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1639 LPWSTR filename = NULL;
1640 HRESULT hr = S_FALSE;
1641 IXMLDOMDocument3 *pNewDoc = NULL;
1642 IStream *pStream = NULL;
1643 xmlDocPtr xmldoc;
1645 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1647 *isSuccessful = VARIANT_FALSE;
1649 assert( &This->node );
1651 switch( V_VT(&xmlSource) )
1653 case VT_BSTR:
1654 filename = V_BSTR(&xmlSource);
1655 break;
1656 case VT_UNKNOWN:
1657 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument3, (void**)&pNewDoc);
1658 if(hr == S_OK)
1660 if(pNewDoc)
1662 domdoc *newDoc = impl_from_IXMLDOMDocument3( pNewDoc );
1663 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1664 hr = attach_xmldoc(&This->node, xmldoc);
1666 if(SUCCEEDED(hr))
1667 *isSuccessful = VARIANT_TRUE;
1669 return hr;
1672 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1673 if(hr == S_OK)
1675 IPersistStream *pDocStream;
1676 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1677 if(hr == S_OK)
1679 hr = IPersistStream_Load(pDocStream, pStream);
1680 IStream_Release(pStream);
1681 if(hr == S_OK)
1683 *isSuccessful = VARIANT_TRUE;
1685 TRACE("Using IStream to load Document\n");
1686 return S_OK;
1688 else
1690 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1693 else
1695 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1698 else
1700 /* ISequentialStream */
1701 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1703 break;
1704 default:
1705 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1708 TRACE("filename (%s)\n", debugstr_w(filename));
1710 if ( filename )
1712 hr = doread( This, filename );
1714 if ( FAILED(hr) )
1715 This->error = E_FAIL;
1716 else
1718 hr = This->error = S_OK;
1719 *isSuccessful = VARIANT_TRUE;
1723 if(!filename || FAILED(hr)) {
1724 xmldoc = xmlNewDoc(NULL);
1725 xmldoc->_private = create_priv();
1726 hr = attach_xmldoc(&This->node, xmldoc);
1727 if(SUCCEEDED(hr))
1728 hr = S_FALSE;
1731 TRACE("ret (%d)\n", hr);
1733 return hr;
1737 static HRESULT WINAPI domdoc_get_readyState(
1738 IXMLDOMDocument3 *iface,
1739 LONG *value )
1741 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1742 FIXME("(%p)->(%p)\n", This, value);
1743 return E_NOTIMPL;
1747 static HRESULT WINAPI domdoc_get_parseError(
1748 IXMLDOMDocument3 *iface,
1749 IXMLDOMParseError** errorObj )
1751 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1752 static const WCHAR err[] = {'e','r','r','o','r',0};
1753 BSTR error_string = NULL;
1755 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1757 if(This->error)
1758 error_string = SysAllocString(err);
1760 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1761 if(!*errorObj) return E_OUTOFMEMORY;
1762 return S_OK;
1766 static HRESULT WINAPI domdoc_get_url(
1767 IXMLDOMDocument3 *iface,
1768 BSTR* urlString )
1770 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1771 FIXME("(%p)->(%p)\n", This, urlString);
1772 return E_NOTIMPL;
1776 static HRESULT WINAPI domdoc_get_async(
1777 IXMLDOMDocument3 *iface,
1778 VARIANT_BOOL* isAsync )
1780 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1782 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1783 *isAsync = This->async;
1784 return S_OK;
1788 static HRESULT WINAPI domdoc_put_async(
1789 IXMLDOMDocument3 *iface,
1790 VARIANT_BOOL isAsync )
1792 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1794 TRACE("(%p)->(%d)\n", This, isAsync);
1795 This->async = isAsync;
1796 return S_OK;
1800 static HRESULT WINAPI domdoc_abort(
1801 IXMLDOMDocument3 *iface )
1803 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1804 FIXME("%p\n", This);
1805 return E_NOTIMPL;
1809 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1811 UINT len;
1812 LPSTR str;
1814 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1815 str = heap_alloc( len );
1816 if ( !str )
1817 return FALSE;
1818 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
1819 *plen = len;
1820 *pstr = str;
1821 return TRUE;
1824 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
1825 static HRESULT WINAPI domdoc_loadXML(
1826 IXMLDOMDocument3 *iface,
1827 BSTR bstrXML,
1828 VARIANT_BOOL* isSuccessful )
1830 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1831 xmlDocPtr xmldoc = NULL;
1832 HRESULT hr = S_FALSE, hr2;
1833 char *str;
1834 int len;
1836 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
1838 assert ( &This->node );
1840 if ( isSuccessful )
1842 *isSuccessful = VARIANT_FALSE;
1844 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1846 xmldoc = doparse( str, len, "UTF-8" );
1847 heap_free( str );
1848 if ( !xmldoc )
1849 This->error = E_FAIL;
1850 else
1852 hr = This->error = S_OK;
1853 *isSuccessful = VARIANT_TRUE;
1854 TRACE("parsed document %p\n", xmldoc);
1858 if(!xmldoc)
1859 xmldoc = xmlNewDoc(NULL);
1861 xmldoc->_private = create_priv();
1862 hr2 = attach_xmldoc( &This->node, xmldoc );
1863 if( FAILED(hr2) )
1864 hr = hr2;
1866 return hr;
1869 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1870 int len)
1872 DWORD written = -1;
1874 if(!WriteFile(ctx, buffer, len, &written, NULL))
1876 WARN("write error\n");
1877 return -1;
1879 else
1880 return written;
1883 static int XMLCALL domdoc_save_closecallback(void *ctx)
1885 return CloseHandle(ctx) ? 0 : -1;
1888 static HRESULT WINAPI domdoc_save(
1889 IXMLDOMDocument3 *iface,
1890 VARIANT destination )
1892 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1893 HANDLE handle;
1894 xmlSaveCtxtPtr ctx;
1895 xmlNodePtr xmldecl;
1896 HRESULT ret = S_OK;
1898 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1899 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1901 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1903 FIXME("Unhandled vt %d\n", V_VT(&destination));
1904 return S_FALSE;
1907 if(V_VT(&destination) == VT_UNKNOWN)
1909 IUnknown *pUnk = V_UNKNOWN(&destination);
1910 IXMLDOMDocument2 *pDocument;
1912 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&pDocument);
1913 if(ret == S_OK)
1915 VARIANT_BOOL success;
1916 BSTR xml;
1918 ret = IXMLDOMDocument3_get_xml(iface, &xml);
1919 if(ret == S_OK)
1921 ret = IXMLDOMDocument3_loadXML(pDocument, xml, &success);
1922 SysFreeString(xml);
1925 IXMLDOMDocument3_Release(pDocument);
1928 TRACE("ret %d\n", ret);
1930 return ret;
1933 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1934 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1935 if( handle == INVALID_HANDLE_VALUE )
1937 WARN("failed to create file\n");
1938 return S_FALSE;
1941 /* disable top XML declaration */
1942 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1943 handle, NULL, XML_SAVE_NO_DECL);
1944 if (!ctx)
1946 CloseHandle(handle);
1947 return S_FALSE;
1950 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
1951 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1952 xmldoc_link_xmldecl(get_doc(This), xmldecl);
1954 /* will close file through close callback */
1955 xmlSaveClose(ctx);
1957 return ret;
1960 static HRESULT WINAPI domdoc_get_validateOnParse(
1961 IXMLDOMDocument3 *iface,
1962 VARIANT_BOOL* isValidating )
1964 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1965 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
1966 *isValidating = This->validating;
1967 return S_OK;
1971 static HRESULT WINAPI domdoc_put_validateOnParse(
1972 IXMLDOMDocument3 *iface,
1973 VARIANT_BOOL isValidating )
1975 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1976 TRACE("(%p)->(%d)\n", This, isValidating);
1977 This->validating = isValidating;
1978 return S_OK;
1982 static HRESULT WINAPI domdoc_get_resolveExternals(
1983 IXMLDOMDocument3 *iface,
1984 VARIANT_BOOL* isResolving )
1986 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1987 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
1988 *isResolving = This->resolving;
1989 return S_OK;
1993 static HRESULT WINAPI domdoc_put_resolveExternals(
1994 IXMLDOMDocument3 *iface,
1995 VARIANT_BOOL isResolving )
1997 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1998 TRACE("(%p)->(%d)\n", This, isResolving);
1999 This->resolving = isResolving;
2000 return S_OK;
2004 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
2005 IXMLDOMDocument3 *iface,
2006 VARIANT_BOOL* isPreserving )
2008 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2009 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
2010 *isPreserving = This->preserving;
2011 return S_OK;
2015 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
2016 IXMLDOMDocument3 *iface,
2017 VARIANT_BOOL isPreserving )
2019 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2020 TRACE("(%p)->(%d)\n", This, isPreserving);
2021 This->preserving = isPreserving;
2022 return S_OK;
2026 static HRESULT WINAPI domdoc_put_onReadyStateChange(
2027 IXMLDOMDocument3 *iface,
2028 VARIANT readyStateChangeSink )
2030 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2031 FIXME("%p\n", This);
2032 return E_NOTIMPL;
2036 static HRESULT WINAPI domdoc_put_onDataAvailable(
2037 IXMLDOMDocument3 *iface,
2038 VARIANT onDataAvailableSink )
2040 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2041 FIXME("%p\n", This);
2042 return E_NOTIMPL;
2045 static HRESULT WINAPI domdoc_put_onTransformNode(
2046 IXMLDOMDocument3 *iface,
2047 VARIANT onTransformNodeSink )
2049 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2050 FIXME("%p\n", This);
2051 return E_NOTIMPL;
2054 static HRESULT WINAPI domdoc_get_namespaces(
2055 IXMLDOMDocument3* iface,
2056 IXMLDOMSchemaCollection** schemaCollection )
2058 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2059 FIXME("(%p)->(%p)\n", This, schemaCollection);
2060 return E_NOTIMPL;
2063 static HRESULT WINAPI domdoc_get_schemas(
2064 IXMLDOMDocument3* iface,
2065 VARIANT* var1 )
2067 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2068 HRESULT hr = S_FALSE;
2069 IXMLDOMSchemaCollection *cur_schema = This->schema;
2071 TRACE("(%p)->(%p)\n", This, var1);
2073 VariantInit(var1); /* Test shows we don't call VariantClear here */
2074 V_VT(var1) = VT_NULL;
2076 if(cur_schema)
2078 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
2079 if(SUCCEEDED(hr))
2080 V_VT(var1) = VT_DISPATCH;
2082 return hr;
2085 static HRESULT WINAPI domdoc_putref_schemas(
2086 IXMLDOMDocument3* iface,
2087 VARIANT var1)
2089 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2090 HRESULT hr = E_FAIL;
2091 IXMLDOMSchemaCollection *new_schema = NULL;
2093 FIXME("(%p): semi-stub\n", This);
2094 switch(V_VT(&var1))
2096 case VT_UNKNOWN:
2097 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2098 break;
2100 case VT_DISPATCH:
2101 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2102 break;
2104 case VT_NULL:
2105 case VT_EMPTY:
2106 hr = S_OK;
2107 break;
2109 default:
2110 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2113 if(SUCCEEDED(hr))
2115 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2116 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2119 return hr;
2122 static HRESULT WINAPI domdoc_validate(
2123 IXMLDOMDocument3* iface,
2124 IXMLDOMParseError** err)
2126 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2127 FIXME("(%p)->(%p)\n", This, err);
2128 return E_NOTIMPL;
2131 static HRESULT WINAPI domdoc_setProperty(
2132 IXMLDOMDocument3* iface,
2133 BSTR p,
2134 VARIANT var)
2136 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2138 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2140 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2142 VARIANT varStr;
2143 HRESULT hr;
2144 BSTR bstr;
2146 V_VT(&varStr) = VT_EMPTY;
2147 if (V_VT(&var) != VT_BSTR)
2149 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2150 return hr;
2151 bstr = V_BSTR(&varStr);
2153 else
2154 bstr = V_BSTR(&var);
2156 hr = S_OK;
2157 if (lstrcmpiW(bstr, PropValueXPathW) == 0)
2158 set_xpathmode(get_doc(This));
2159 else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
2160 reset_xpathmode(get_doc(This));
2161 else
2162 hr = E_FAIL;
2164 VariantClear(&varStr);
2165 return hr;
2167 else if (lstrcmpiW(p, PropertyProhibitDTDW) == 0)
2169 /* Ignore */
2170 FIXME("Ignoring property ProhibitDTD, value %d\n", V_BOOL(&var));
2171 return S_OK;
2173 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2175 if (V_VT(&var) == VT_BSTR)
2176 FIXME("Unsupported SelectionNamespaces: %s\n", wine_dbgstr_w(V_BSTR(&var)));
2177 return E_FAIL;
2180 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2181 return E_FAIL;
2184 static HRESULT WINAPI domdoc_getProperty(
2185 IXMLDOMDocument3* iface,
2186 BSTR p,
2187 VARIANT* var)
2189 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2191 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2193 if (!var)
2194 return E_INVALIDARG;
2196 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2198 V_VT(var) = VT_BSTR;
2199 V_BSTR(var) = is_xpathmode(This->node.node->doc) ?
2200 SysAllocString(PropValueXPathW) :
2201 SysAllocString(PropValueXSLPatternW);
2202 return V_BSTR(var) ? S_OK : E_OUTOFMEMORY;
2205 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2206 return E_FAIL;
2209 static HRESULT WINAPI domdoc_validateNode(
2210 IXMLDOMDocument3* iface,
2211 IXMLDOMNode* node,
2212 IXMLDOMParseError** error)
2214 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2215 FIXME("(%p)->(%p %p): stub\n", This, node, error);
2216 return E_NOTIMPL;
2219 static HRESULT WINAPI domdoc_importNode(
2220 IXMLDOMDocument3* iface,
2221 IXMLDOMNode* node,
2222 VARIANT_BOOL deep,
2223 IXMLDOMNode** clone)
2225 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2226 FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone);
2227 return E_NOTIMPL;
2230 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl =
2232 domdoc_QueryInterface,
2233 domdoc_AddRef,
2234 domdoc_Release,
2235 domdoc_GetTypeInfoCount,
2236 domdoc_GetTypeInfo,
2237 domdoc_GetIDsOfNames,
2238 domdoc_Invoke,
2239 domdoc_get_nodeName,
2240 domdoc_get_nodeValue,
2241 domdoc_put_nodeValue,
2242 domdoc_get_nodeType,
2243 domdoc_get_parentNode,
2244 domdoc_get_childNodes,
2245 domdoc_get_firstChild,
2246 domdoc_get_lastChild,
2247 domdoc_get_previousSibling,
2248 domdoc_get_nextSibling,
2249 domdoc_get_attributes,
2250 domdoc_insertBefore,
2251 domdoc_replaceChild,
2252 domdoc_removeChild,
2253 domdoc_appendChild,
2254 domdoc_hasChildNodes,
2255 domdoc_get_ownerDocument,
2256 domdoc_cloneNode,
2257 domdoc_get_nodeTypeString,
2258 domdoc_get_text,
2259 domdoc_put_text,
2260 domdoc_get_specified,
2261 domdoc_get_definition,
2262 domdoc_get_nodeTypedValue,
2263 domdoc_put_nodeTypedValue,
2264 domdoc_get_dataType,
2265 domdoc_put_dataType,
2266 domdoc_get_xml,
2267 domdoc_transformNode,
2268 domdoc_selectNodes,
2269 domdoc_selectSingleNode,
2270 domdoc_get_parsed,
2271 domdoc_get_namespaceURI,
2272 domdoc_get_prefix,
2273 domdoc_get_baseName,
2274 domdoc_transformNodeToObject,
2275 domdoc_get_doctype,
2276 domdoc_get_implementation,
2277 domdoc_get_documentElement,
2278 domdoc_put_documentElement,
2279 domdoc_createElement,
2280 domdoc_createDocumentFragment,
2281 domdoc_createTextNode,
2282 domdoc_createComment,
2283 domdoc_createCDATASection,
2284 domdoc_createProcessingInstruction,
2285 domdoc_createAttribute,
2286 domdoc_createEntityReference,
2287 domdoc_getElementsByTagName,
2288 domdoc_createNode,
2289 domdoc_nodeFromID,
2290 domdoc_load,
2291 domdoc_get_readyState,
2292 domdoc_get_parseError,
2293 domdoc_get_url,
2294 domdoc_get_async,
2295 domdoc_put_async,
2296 domdoc_abort,
2297 domdoc_loadXML,
2298 domdoc_save,
2299 domdoc_get_validateOnParse,
2300 domdoc_put_validateOnParse,
2301 domdoc_get_resolveExternals,
2302 domdoc_put_resolveExternals,
2303 domdoc_get_preserveWhiteSpace,
2304 domdoc_put_preserveWhiteSpace,
2305 domdoc_put_onReadyStateChange,
2306 domdoc_put_onDataAvailable,
2307 domdoc_put_onTransformNode,
2308 domdoc_get_namespaces,
2309 domdoc_get_schemas,
2310 domdoc_putref_schemas,
2311 domdoc_validate,
2312 domdoc_setProperty,
2313 domdoc_getProperty,
2314 domdoc_validateNode,
2315 domdoc_importNode
2318 /* xmldoc implementation of IObjectWithSite */
2319 static HRESULT WINAPI
2320 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2322 domdoc *This = impl_from_IObjectWithSite(iface);
2323 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2326 static ULONG WINAPI
2327 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2329 domdoc *This = impl_from_IObjectWithSite(iface);
2330 return IXMLDocument_AddRef((IXMLDocument *)This);
2333 static ULONG WINAPI
2334 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2336 domdoc *This = impl_from_IObjectWithSite(iface);
2337 return IXMLDocument_Release((IXMLDocument *)This);
2340 static HRESULT WINAPI
2341 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2343 domdoc *This = impl_from_IObjectWithSite(iface);
2345 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2347 if ( !This->site )
2348 return E_FAIL;
2350 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2353 static HRESULT WINAPI
2354 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2356 domdoc *This = impl_from_IObjectWithSite(iface);
2358 TRACE("(%p)->(%p)\n", iface, punk);
2360 if(!punk)
2362 if(This->site)
2364 IUnknown_Release( This->site );
2365 This->site = NULL;
2368 return S_OK;
2371 IUnknown_AddRef( punk );
2373 if(This->site)
2374 IUnknown_Release( This->site );
2376 This->site = punk;
2378 return S_OK;
2381 static const IObjectWithSiteVtbl domdocObjectSite =
2383 xmldoc_ObjectWithSite_QueryInterface,
2384 xmldoc_ObjectWithSite_AddRef,
2385 xmldoc_ObjectWithSite_Release,
2386 xmldoc_SetSite,
2387 xmldoc_GetSite,
2390 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2392 domdoc *This = impl_from_IObjectSafety(iface);
2393 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2396 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2398 domdoc *This = impl_from_IObjectSafety(iface);
2399 return IXMLDocument_AddRef((IXMLDocument *)This);
2402 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2404 domdoc *This = impl_from_IObjectSafety(iface);
2405 return IXMLDocument_Release((IXMLDocument *)This);
2408 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2410 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2411 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2413 domdoc *This = impl_from_IObjectSafety(iface);
2415 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2417 if(!pdwSupportedOptions || !pdwEnabledOptions)
2418 return E_POINTER;
2420 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2421 *pdwEnabledOptions = This->safeopt;
2423 return S_OK;
2426 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2427 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2429 domdoc *This = impl_from_IObjectSafety(iface);
2430 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2432 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2433 return E_FAIL;
2435 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2436 return S_OK;
2439 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2440 xmldoc_Safety_QueryInterface,
2441 xmldoc_Safety_AddRef,
2442 xmldoc_Safety_Release,
2443 xmldoc_Safety_GetInterfaceSafetyOptions,
2444 xmldoc_Safety_SetInterfaceSafetyOptions
2448 static const tid_t domdoc_iface_tids[] = {
2449 IXMLDOMNode_tid,
2450 IXMLDOMDocument_tid,
2451 IXMLDOMDocument2_tid,
2454 static dispex_static_data_t domdoc_dispex = {
2455 NULL,
2456 IXMLDOMDocument2_tid,
2457 NULL,
2458 domdoc_iface_tids
2461 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
2463 domdoc *doc;
2465 doc = heap_alloc( sizeof (*doc) );
2466 if( !doc )
2467 return E_OUTOFMEMORY;
2469 doc->lpVtbl = &domdoc_vtbl;
2470 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2471 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2472 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2473 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2474 doc->ref = 1;
2475 doc->async = VARIANT_TRUE;
2476 doc->validating = 0;
2477 doc->resolving = 0;
2478 doc->preserving = 0;
2479 doc->error = S_OK;
2480 doc->schema = NULL;
2481 doc->stream = NULL;
2482 doc->site = NULL;
2483 doc->safeopt = 0;
2484 doc->bsc = NULL;
2486 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IXMLDOMNode*)&doc->lpVtbl, &domdoc_dispex);
2488 *document = (IXMLDOMDocument3*)&doc->lpVtbl;
2490 TRACE("returning iface %p\n", *document);
2491 return S_OK;
2494 HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
2496 xmlDocPtr xmldoc;
2497 HRESULT hr;
2499 TRACE("(%s, %p, %p)\n", debugstr_guid(clsid), pUnkOuter, ppObj);
2501 xmldoc = xmlNewDoc(NULL);
2502 if(!xmldoc)
2503 return E_OUTOFMEMORY;
2505 xmldoc->_private = create_priv();
2507 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj);
2508 if(FAILED(hr))
2510 xmlFreeDoc(xmldoc);
2511 return hr;
2514 /* properties that are dependent on object versions */
2515 if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) ||
2516 IsEqualCLSID( clsid, &CLSID_DOMDocument60 ))
2518 domdoc *This = impl_from_IXMLDOMDocument3(*ppObj);
2519 set_xpathmode(get_doc(This));
2522 return hr;
2525 IUnknown* create_domdoc( xmlNodePtr document )
2527 void* pObj = NULL;
2528 HRESULT hr;
2530 TRACE("(%p)\n", document);
2532 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
2533 if (FAILED(hr))
2534 return NULL;
2536 return pObj;
2539 #else
2541 HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
2543 MESSAGE("This program tried to use a DOMDocument object, but\n"
2544 "libxml2 support was not present at compile time.\n");
2545 return E_NOTIMPL;
2548 #endif