push ac8730bd9057ca84ecf262ddc5d43fb7b5849da7
[wine/hacks.git] / dlls / msxml3 / domdoc.c
blob41cd8561b148b40854590b7bd7808c9bd4efdde9
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"
43 #include "msxml_private.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
47 #ifdef HAVE_LIBXML2
49 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};
50 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
51 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
53 typedef struct _domdoc
55 const struct IXMLDOMDocument2Vtbl *lpVtbl;
56 const struct IPersistStreamVtbl *lpvtblIPersistStream;
57 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
58 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
59 LONG ref;
60 VARIANT_BOOL async;
61 VARIANT_BOOL validating;
62 VARIANT_BOOL resolving;
63 VARIANT_BOOL preserving;
64 BOOL bUseXPath;
65 IUnknown *node_unk;
66 IXMLDOMNode *node;
67 IXMLDOMSchemaCollection *schema;
68 bsc_t *bsc;
69 HRESULT error;
71 /* IPersistStream */
72 IStream *stream;
74 /* IObjectWithSite*/
75 IUnknown *site;
77 /* IObjectSafety */
78 DWORD safeopt;
80 /* IDispatchEx */
81 DispatchEx dispex;
82 } domdoc;
84 static xmlDocPtr doparse( char *ptr, int len )
86 #ifdef HAVE_XMLREADMEMORY
88 * use xmlReadMemory if possible so we can suppress
89 * writing errors to stderr
91 return xmlReadMemory( ptr, len, NULL, NULL,
92 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
93 #else
94 return xmlParseMemory( ptr, len );
95 #endif
98 LONG xmldoc_add_ref(xmlDocPtr doc)
100 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
101 TRACE("%d\n", ref);
102 return ref;
105 LONG xmldoc_release(xmlDocPtr doc)
107 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
108 TRACE("%d\n", ref);
109 if(ref == 0)
111 TRACE("freeing docptr %p\n", doc);
112 xmlFreeDoc(doc);
115 return ref;
118 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
120 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
123 static inline xmlDocPtr get_doc( domdoc *This )
125 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
128 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
130 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
133 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
135 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
138 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
140 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
144 /************************************************************************
145 * xmldoc implementation of IPersistStream.
147 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
148 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
150 domdoc *this = impl_from_IPersistStream(iface);
151 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
154 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
155 IPersistStream *iface)
157 domdoc *this = impl_from_IPersistStream(iface);
158 return IXMLDocument_AddRef((IXMLDocument *)this);
161 static ULONG WINAPI xmldoc_IPersistStream_Release(
162 IPersistStream *iface)
164 domdoc *this = impl_from_IPersistStream(iface);
165 return IXMLDocument_Release((IXMLDocument *)this);
168 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
169 IPersistStream *iface, CLSID *classid)
171 TRACE("(%p,%p): stub!\n", iface, classid);
173 if(!classid)
174 return E_POINTER;
176 *classid = CLSID_DOMDocument2;
178 return S_OK;
181 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
182 IPersistStream *iface)
184 domdoc *This = impl_from_IPersistStream(iface);
186 FIXME("(%p->%p): stub!\n", iface, This);
188 return S_FALSE;
191 static HRESULT WINAPI xmldoc_IPersistStream_Load(
192 IPersistStream *iface, LPSTREAM pStm)
194 domdoc *This = impl_from_IPersistStream(iface);
195 HRESULT hr;
196 HGLOBAL hglobal;
197 DWORD read, written, len;
198 BYTE buf[4096];
199 char *ptr;
200 xmlDocPtr xmldoc = NULL;
202 TRACE("(%p, %p)\n", iface, pStm);
204 if (!pStm)
205 return E_INVALIDARG;
207 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
208 if (FAILED(hr))
209 return hr;
213 IStream_Read(pStm, buf, sizeof(buf), &read);
214 hr = IStream_Write(This->stream, buf, read, &written);
215 } while(SUCCEEDED(hr) && written != 0 && read != 0);
217 if (FAILED(hr))
219 ERR("Failed to copy stream\n");
220 return hr;
223 hr = GetHGlobalFromStream(This->stream, &hglobal);
224 if (FAILED(hr))
225 return hr;
227 len = GlobalSize(hglobal);
228 ptr = GlobalLock(hglobal);
229 if (len != 0)
230 xmldoc = parse_xml(ptr, len);
231 GlobalUnlock(hglobal);
233 if (!xmldoc)
235 ERR("Failed to parse xml\n");
236 return E_FAIL;
239 attach_xmlnode( This->node, (xmlNodePtr)xmldoc );
241 return S_OK;
244 static HRESULT WINAPI xmldoc_IPersistStream_Save(
245 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
247 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
248 return E_NOTIMPL;
251 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
252 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
254 TRACE("(%p, %p): stub!\n", iface, pcbSize);
255 return E_NOTIMPL;
258 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
260 xmldoc_IPersistStream_QueryInterface,
261 xmldoc_IPersistStream_AddRef,
262 xmldoc_IPersistStream_Release,
263 xmldoc_IPersistStream_GetClassID,
264 xmldoc_IPersistStream_IsDirty,
265 xmldoc_IPersistStream_Load,
266 xmldoc_IPersistStream_Save,
267 xmldoc_IPersistStream_GetSizeMax,
270 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
272 domdoc *This = impl_from_IXMLDOMDocument2( iface );
274 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
276 *ppvObject = NULL;
278 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
279 IsEqualGUID( riid, &IID_IDispatch ) ||
280 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
281 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
283 *ppvObject = iface;
285 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
287 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
289 else if (IsEqualGUID(&IID_IPersistStream, riid))
291 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
293 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
295 *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite);
297 else if(dispex_query_interface(&This->dispex, riid, ppvObject))
299 return *ppvObject ? S_OK : E_NOINTERFACE;
301 else if(IsEqualGUID(&IID_IRunnableObject, riid))
303 TRACE("IID_IRunnableObject not supported returning NULL\n");
304 return E_NOINTERFACE;
306 else
308 FIXME("interface %s not implemented\n", debugstr_guid(riid));
309 return E_NOINTERFACE;
312 IXMLDOMDocument_AddRef( iface );
314 return S_OK;
318 static ULONG WINAPI domdoc_AddRef(
319 IXMLDOMDocument2 *iface )
321 domdoc *This = impl_from_IXMLDOMDocument2( iface );
322 TRACE("%p\n", This );
323 return InterlockedIncrement( &This->ref );
327 static ULONG WINAPI domdoc_Release(
328 IXMLDOMDocument2 *iface )
330 domdoc *This = impl_from_IXMLDOMDocument2( iface );
331 LONG ref;
333 TRACE("%p\n", This );
335 ref = InterlockedDecrement( &This->ref );
336 if ( ref == 0 )
338 if(This->bsc)
339 detach_bsc(This->bsc);
341 if (This->site)
342 IUnknown_Release( This->site );
343 IUnknown_Release( This->node_unk );
344 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
345 if (This->stream) IStream_Release(This->stream);
346 HeapFree( GetProcessHeap(), 0, This );
349 return ref;
352 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
354 domdoc *This = impl_from_IXMLDOMDocument2( iface );
356 TRACE("(%p)->(%p)\n", This, pctinfo);
358 *pctinfo = 1;
360 return S_OK;
363 static HRESULT WINAPI domdoc_GetTypeInfo(
364 IXMLDOMDocument2 *iface,
365 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
367 domdoc *This = impl_from_IXMLDOMDocument2( iface );
368 HRESULT hr;
370 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
372 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
374 return hr;
377 static HRESULT WINAPI domdoc_GetIDsOfNames(
378 IXMLDOMDocument2 *iface,
379 REFIID riid,
380 LPOLESTR* rgszNames,
381 UINT cNames,
382 LCID lcid,
383 DISPID* rgDispId)
385 domdoc *This = impl_from_IXMLDOMDocument2( iface );
386 ITypeInfo *typeinfo;
387 HRESULT hr;
389 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
390 lcid, rgDispId);
392 if(!rgszNames || cNames == 0 || !rgDispId)
393 return E_INVALIDARG;
395 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
396 if(SUCCEEDED(hr))
398 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
399 ITypeInfo_Release(typeinfo);
402 return hr;
406 static HRESULT WINAPI domdoc_Invoke(
407 IXMLDOMDocument2 *iface,
408 DISPID dispIdMember,
409 REFIID riid,
410 LCID lcid,
411 WORD wFlags,
412 DISPPARAMS* pDispParams,
413 VARIANT* pVarResult,
414 EXCEPINFO* pExcepInfo,
415 UINT* puArgErr)
417 domdoc *This = impl_from_IXMLDOMDocument2( iface );
418 ITypeInfo *typeinfo;
419 HRESULT hr;
421 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
422 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
424 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
425 if(SUCCEEDED(hr))
427 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
428 pVarResult, pExcepInfo, puArgErr);
429 ITypeInfo_Release(typeinfo);
432 return hr;
436 static HRESULT WINAPI domdoc_get_nodeName(
437 IXMLDOMDocument2 *iface,
438 BSTR* name )
440 domdoc *This = impl_from_IXMLDOMDocument2( iface );
441 return IXMLDOMNode_get_nodeName( This->node, name );
445 static HRESULT WINAPI domdoc_get_nodeValue(
446 IXMLDOMDocument2 *iface,
447 VARIANT* value )
449 domdoc *This = impl_from_IXMLDOMDocument2( iface );
450 return IXMLDOMNode_get_nodeValue( This->node, value );
454 static HRESULT WINAPI domdoc_put_nodeValue(
455 IXMLDOMDocument2 *iface,
456 VARIANT value)
458 domdoc *This = impl_from_IXMLDOMDocument2( iface );
459 return IXMLDOMNode_put_nodeValue( This->node, value );
463 static HRESULT WINAPI domdoc_get_nodeType(
464 IXMLDOMDocument2 *iface,
465 DOMNodeType* type )
467 domdoc *This = impl_from_IXMLDOMDocument2( iface );
468 return IXMLDOMNode_get_nodeType( This->node, type );
472 static HRESULT WINAPI domdoc_get_parentNode(
473 IXMLDOMDocument2 *iface,
474 IXMLDOMNode** parent )
476 domdoc *This = impl_from_IXMLDOMDocument2( iface );
477 return IXMLDOMNode_get_parentNode( This->node, parent );
481 static HRESULT WINAPI domdoc_get_childNodes(
482 IXMLDOMDocument2 *iface,
483 IXMLDOMNodeList** childList )
485 domdoc *This = impl_from_IXMLDOMDocument2( iface );
486 return IXMLDOMNode_get_childNodes( This->node, childList );
490 static HRESULT WINAPI domdoc_get_firstChild(
491 IXMLDOMDocument2 *iface,
492 IXMLDOMNode** firstChild )
494 domdoc *This = impl_from_IXMLDOMDocument2( iface );
495 return IXMLDOMNode_get_firstChild( This->node, firstChild );
499 static HRESULT WINAPI domdoc_get_lastChild(
500 IXMLDOMDocument2 *iface,
501 IXMLDOMNode** lastChild )
503 domdoc *This = impl_from_IXMLDOMDocument2( iface );
504 return IXMLDOMNode_get_lastChild( This->node, lastChild );
508 static HRESULT WINAPI domdoc_get_previousSibling(
509 IXMLDOMDocument2 *iface,
510 IXMLDOMNode** previousSibling )
512 domdoc *This = impl_from_IXMLDOMDocument2( iface );
513 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
517 static HRESULT WINAPI domdoc_get_nextSibling(
518 IXMLDOMDocument2 *iface,
519 IXMLDOMNode** nextSibling )
521 domdoc *This = impl_from_IXMLDOMDocument2( iface );
522 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
526 static HRESULT WINAPI domdoc_get_attributes(
527 IXMLDOMDocument2 *iface,
528 IXMLDOMNamedNodeMap** attributeMap )
530 domdoc *This = impl_from_IXMLDOMDocument2( iface );
531 return IXMLDOMNode_get_attributes( This->node, attributeMap );
535 static HRESULT WINAPI domdoc_insertBefore(
536 IXMLDOMDocument2 *iface,
537 IXMLDOMNode* newChild,
538 VARIANT refChild,
539 IXMLDOMNode** outNewChild )
541 domdoc *This = impl_from_IXMLDOMDocument2( iface );
542 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
546 static HRESULT WINAPI domdoc_replaceChild(
547 IXMLDOMDocument2 *iface,
548 IXMLDOMNode* newChild,
549 IXMLDOMNode* oldChild,
550 IXMLDOMNode** outOldChild)
552 domdoc *This = impl_from_IXMLDOMDocument2( iface );
553 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
557 static HRESULT WINAPI domdoc_removeChild(
558 IXMLDOMDocument2 *iface,
559 IXMLDOMNode* childNode,
560 IXMLDOMNode** oldChild)
562 domdoc *This = impl_from_IXMLDOMDocument2( iface );
563 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
567 static HRESULT WINAPI domdoc_appendChild(
568 IXMLDOMDocument2 *iface,
569 IXMLDOMNode* newChild,
570 IXMLDOMNode** outNewChild)
572 domdoc *This = impl_from_IXMLDOMDocument2( iface );
573 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
577 static HRESULT WINAPI domdoc_hasChildNodes(
578 IXMLDOMDocument2 *iface,
579 VARIANT_BOOL* hasChild)
581 domdoc *This = impl_from_IXMLDOMDocument2( iface );
582 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
586 static HRESULT WINAPI domdoc_get_ownerDocument(
587 IXMLDOMDocument2 *iface,
588 IXMLDOMDocument** DOMDocument)
590 domdoc *This = impl_from_IXMLDOMDocument2( iface );
591 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
595 static HRESULT WINAPI domdoc_cloneNode(
596 IXMLDOMDocument2 *iface,
597 VARIANT_BOOL deep,
598 IXMLDOMNode** cloneRoot)
600 domdoc *This = impl_from_IXMLDOMDocument2( iface );
601 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
605 static HRESULT WINAPI domdoc_get_nodeTypeString(
606 IXMLDOMDocument2 *iface,
607 BSTR* nodeType )
609 domdoc *This = impl_from_IXMLDOMDocument2( iface );
610 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
614 static HRESULT WINAPI domdoc_get_text(
615 IXMLDOMDocument2 *iface,
616 BSTR* text )
618 domdoc *This = impl_from_IXMLDOMDocument2( iface );
619 return IXMLDOMNode_get_text( This->node, text );
623 static HRESULT WINAPI domdoc_put_text(
624 IXMLDOMDocument2 *iface,
625 BSTR text )
627 domdoc *This = impl_from_IXMLDOMDocument2( iface );
628 return IXMLDOMNode_put_text( This->node, text );
632 static HRESULT WINAPI domdoc_get_specified(
633 IXMLDOMDocument2 *iface,
634 VARIANT_BOOL* isSpecified )
636 domdoc *This = impl_from_IXMLDOMDocument2( iface );
637 return IXMLDOMNode_get_specified( This->node, isSpecified );
641 static HRESULT WINAPI domdoc_get_definition(
642 IXMLDOMDocument2 *iface,
643 IXMLDOMNode** definitionNode )
645 domdoc *This = impl_from_IXMLDOMDocument2( iface );
646 return IXMLDOMNode_get_definition( This->node, definitionNode );
650 static HRESULT WINAPI domdoc_get_nodeTypedValue(
651 IXMLDOMDocument2 *iface,
652 VARIANT* typedValue )
654 domdoc *This = impl_from_IXMLDOMDocument2( iface );
655 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
658 static HRESULT WINAPI domdoc_put_nodeTypedValue(
659 IXMLDOMDocument2 *iface,
660 VARIANT typedValue )
662 domdoc *This = impl_from_IXMLDOMDocument2( iface );
663 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
667 static HRESULT WINAPI domdoc_get_dataType(
668 IXMLDOMDocument2 *iface,
669 VARIANT* dataTypeName )
671 domdoc *This = impl_from_IXMLDOMDocument2( iface );
672 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
676 static HRESULT WINAPI domdoc_put_dataType(
677 IXMLDOMDocument2 *iface,
678 BSTR dataTypeName )
680 domdoc *This = impl_from_IXMLDOMDocument2( iface );
681 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
685 static HRESULT WINAPI domdoc_get_xml(
686 IXMLDOMDocument2 *iface,
687 BSTR* xmlString )
689 domdoc *This = impl_from_IXMLDOMDocument2( iface );
690 return IXMLDOMNode_get_xml( This->node, xmlString );
694 static HRESULT WINAPI domdoc_transformNode(
695 IXMLDOMDocument2 *iface,
696 IXMLDOMNode* styleSheet,
697 BSTR* xmlString )
699 domdoc *This = impl_from_IXMLDOMDocument2( iface );
700 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
704 static HRESULT WINAPI domdoc_selectNodes(
705 IXMLDOMDocument2 *iface,
706 BSTR queryString,
707 IXMLDOMNodeList** resultList )
709 domdoc *This = impl_from_IXMLDOMDocument2( iface );
710 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
714 static HRESULT WINAPI domdoc_selectSingleNode(
715 IXMLDOMDocument2 *iface,
716 BSTR queryString,
717 IXMLDOMNode** resultNode )
719 domdoc *This = impl_from_IXMLDOMDocument2( iface );
720 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
724 static HRESULT WINAPI domdoc_get_parsed(
725 IXMLDOMDocument2 *iface,
726 VARIANT_BOOL* isParsed )
728 domdoc *This = impl_from_IXMLDOMDocument2( iface );
729 return IXMLDOMNode_get_parsed( This->node, isParsed );
733 static HRESULT WINAPI domdoc_get_namespaceURI(
734 IXMLDOMDocument2 *iface,
735 BSTR* namespaceURI )
737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
738 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
742 static HRESULT WINAPI domdoc_get_prefix(
743 IXMLDOMDocument2 *iface,
744 BSTR* prefixString )
746 domdoc *This = impl_from_IXMLDOMDocument2( iface );
747 return IXMLDOMNode_get_prefix( This->node, prefixString );
751 static HRESULT WINAPI domdoc_get_baseName(
752 IXMLDOMDocument2 *iface,
753 BSTR* nameString )
755 domdoc *This = impl_from_IXMLDOMDocument2( iface );
756 return IXMLDOMNode_get_baseName( This->node, nameString );
760 static HRESULT WINAPI domdoc_transformNodeToObject(
761 IXMLDOMDocument2 *iface,
762 IXMLDOMNode* stylesheet,
763 VARIANT outputObject)
765 domdoc *This = impl_from_IXMLDOMDocument2( iface );
766 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
770 static HRESULT WINAPI domdoc_get_doctype(
771 IXMLDOMDocument2 *iface,
772 IXMLDOMDocumentType** documentType )
774 FIXME("\n");
775 return E_NOTIMPL;
779 static HRESULT WINAPI domdoc_get_implementation(
780 IXMLDOMDocument2 *iface,
781 IXMLDOMImplementation** impl )
783 if(!impl)
784 return E_INVALIDARG;
786 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
788 return S_OK;
791 static HRESULT WINAPI domdoc_get_documentElement(
792 IXMLDOMDocument2 *iface,
793 IXMLDOMElement** DOMElement )
795 domdoc *This = impl_from_IXMLDOMDocument2( iface );
796 xmlDocPtr xmldoc = NULL;
797 xmlNodePtr root = NULL;
798 IXMLDOMNode *element_node;
799 HRESULT hr;
801 TRACE("%p %p\n", This, This->node);
803 if(!DOMElement)
804 return E_INVALIDARG;
806 *DOMElement = NULL;
808 xmldoc = get_doc( This );
810 root = xmlDocGetRootElement( xmldoc );
811 if ( !root )
812 return S_FALSE;
814 element_node = create_node( root );
815 if(!element_node) return S_FALSE;
817 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
818 IXMLDOMNode_Release(element_node);
820 return hr;
824 static HRESULT WINAPI domdoc_put_documentElement(
825 IXMLDOMDocument2 *iface,
826 IXMLDOMElement* DOMElement )
828 domdoc *This = impl_from_IXMLDOMDocument2( iface );
829 IXMLDOMNode *elementNode;
830 xmlnode *xmlNode;
831 HRESULT hr;
833 TRACE("(%p)->(%p)\n", This, DOMElement);
835 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
836 if(FAILED(hr))
837 return hr;
839 xmlNode = impl_from_IXMLDOMNode( elementNode );
840 xmlDocSetRootElement( get_doc(This), xmlNode->node);
841 IXMLDOMNode_Release( elementNode );
843 return S_OK;
847 static HRESULT WINAPI domdoc_createElement(
848 IXMLDOMDocument2 *iface,
849 BSTR tagname,
850 IXMLDOMElement** element )
852 xmlNodePtr xmlnode;
853 domdoc *This = impl_from_IXMLDOMDocument2( iface );
854 xmlChar *xml_name;
855 IUnknown *elem_unk;
856 HRESULT hr;
858 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
860 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
861 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
863 TRACE("created xmlptr %p\n", xmlnode);
864 elem_unk = create_element(xmlnode, NULL);
865 HeapFree(GetProcessHeap(), 0, xml_name);
867 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
868 IUnknown_Release(elem_unk);
869 TRACE("returning %p\n", *element);
870 return hr;
874 static HRESULT WINAPI domdoc_createDocumentFragment(
875 IXMLDOMDocument2 *iface,
876 IXMLDOMDocumentFragment** docFrag )
878 domdoc *This = impl_from_IXMLDOMDocument2( iface );
879 xmlNodePtr xmlnode;
881 TRACE("%p\n", iface);
883 if(!docFrag)
884 return E_INVALIDARG;
886 *docFrag = NULL;
888 xmlnode = xmlNewDocFragment(get_doc( This ) );
890 if(!xmlnode)
891 return E_FAIL;
893 xmlnode->doc = get_doc( This );
895 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
897 return S_OK;
901 static HRESULT WINAPI domdoc_createTextNode(
902 IXMLDOMDocument2 *iface,
903 BSTR data,
904 IXMLDOMText** text )
906 domdoc *This = impl_from_IXMLDOMDocument2( iface );
907 xmlNodePtr xmlnode;
908 xmlChar *xml_content;
910 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
912 if(!text)
913 return E_INVALIDARG;
915 *text = NULL;
917 xml_content = xmlChar_from_wchar((WCHAR*)data);
918 xmlnode = xmlNewText(xml_content);
919 HeapFree(GetProcessHeap(), 0, xml_content);
921 if(!xmlnode)
922 return E_FAIL;
924 xmlnode->doc = get_doc( This );
926 *text = (IXMLDOMText*)create_text(xmlnode);
928 return S_OK;
932 static HRESULT WINAPI domdoc_createComment(
933 IXMLDOMDocument2 *iface,
934 BSTR data,
935 IXMLDOMComment** comment )
937 domdoc *This = impl_from_IXMLDOMDocument2( iface );
938 xmlNodePtr xmlnode;
939 xmlChar *xml_content;
941 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
943 if(!comment)
944 return E_INVALIDARG;
946 *comment = NULL;
948 xml_content = xmlChar_from_wchar((WCHAR*)data);
949 xmlnode = xmlNewComment(xml_content);
950 HeapFree(GetProcessHeap(), 0, xml_content);
952 if(!xmlnode)
953 return E_FAIL;
955 xmlnode->doc = get_doc( This );
957 *comment = (IXMLDOMComment*)create_comment(xmlnode);
959 return S_OK;
963 static HRESULT WINAPI domdoc_createCDATASection(
964 IXMLDOMDocument2 *iface,
965 BSTR data,
966 IXMLDOMCDATASection** cdata )
968 domdoc *This = impl_from_IXMLDOMDocument2( iface );
969 xmlNodePtr xmlnode;
970 xmlChar *xml_content;
972 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
974 if(!cdata)
975 return E_INVALIDARG;
977 *cdata = NULL;
979 xml_content = xmlChar_from_wchar((WCHAR*)data);
980 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
981 HeapFree(GetProcessHeap(), 0, xml_content);
983 if(!xmlnode)
984 return E_FAIL;
986 xmlnode->doc = get_doc( This );
988 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
990 return S_OK;
994 static HRESULT WINAPI domdoc_createProcessingInstruction(
995 IXMLDOMDocument2 *iface,
996 BSTR target,
997 BSTR data,
998 IXMLDOMProcessingInstruction** pi )
1000 #ifdef HAVE_XMLNEWDOCPI
1001 xmlNodePtr xmlnode;
1002 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1003 xmlChar *xml_target, *xml_content;
1005 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1007 if(!pi)
1008 return E_INVALIDARG;
1010 if(!target || lstrlenW(target) == 0)
1011 return E_FAIL;
1013 xml_target = xmlChar_from_wchar((WCHAR*)target);
1014 xml_content = xmlChar_from_wchar((WCHAR*)data);
1016 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1017 TRACE("created xmlptr %p\n", xmlnode);
1018 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1020 HeapFree(GetProcessHeap(), 0, xml_content);
1021 HeapFree(GetProcessHeap(), 0, xml_target);
1023 return S_OK;
1024 #else
1025 FIXME("Libxml 2.6.15 or greater required.\n");
1026 return E_NOTIMPL;
1027 #endif
1031 static HRESULT WINAPI domdoc_createAttribute(
1032 IXMLDOMDocument2 *iface,
1033 BSTR name,
1034 IXMLDOMAttribute** attribute )
1036 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1037 xmlNodePtr xmlnode;
1038 xmlChar *xml_name;
1040 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1042 if(!attribute)
1043 return E_INVALIDARG;
1045 *attribute = NULL;
1047 xml_name = xmlChar_from_wchar((WCHAR*)name);
1048 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1049 HeapFree(GetProcessHeap(), 0, xml_name);
1051 if(!xmlnode)
1052 return E_FAIL;
1054 xmlnode->doc = get_doc( This );
1056 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1058 return S_OK;
1062 static HRESULT WINAPI domdoc_createEntityReference(
1063 IXMLDOMDocument2 *iface,
1064 BSTR name,
1065 IXMLDOMEntityReference** entityRef )
1067 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1068 xmlNodePtr xmlnode;
1069 xmlChar *xml_name;
1071 TRACE("%p\n", iface);
1073 if(!entityRef)
1074 return E_INVALIDARG;
1076 *entityRef = NULL;
1078 xml_name = xmlChar_from_wchar((WCHAR*)name);
1079 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1080 HeapFree(GetProcessHeap(), 0, xml_name);
1082 if(!xmlnode)
1083 return E_FAIL;
1085 xmlnode->doc = get_doc( This );
1087 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1089 return S_OK;
1093 static HRESULT WINAPI domdoc_getElementsByTagName(
1094 IXMLDOMDocument2 *iface,
1095 BSTR tagName,
1096 IXMLDOMNodeList** resultList )
1098 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1099 LPWSTR szPattern;
1100 HRESULT hr;
1101 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1103 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1104 szPattern[0] = szPattern[1] = '/';
1105 lstrcpyW(szPattern + 2, tagName);
1107 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1108 HeapFree(GetProcessHeap(), 0, szPattern);
1110 return hr;
1113 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1115 VARIANT tmp;
1116 HRESULT hr;
1118 VariantInit(&tmp);
1119 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1120 if(FAILED(hr))
1121 return E_INVALIDARG;
1123 *type = V_I4(&tmp);
1125 return S_OK;
1128 static HRESULT WINAPI domdoc_createNode(
1129 IXMLDOMDocument2 *iface,
1130 VARIANT Type,
1131 BSTR name,
1132 BSTR namespaceURI,
1133 IXMLDOMNode** node )
1135 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1136 DOMNodeType node_type;
1137 xmlNodePtr xmlnode = NULL;
1138 xmlChar *xml_name;
1139 HRESULT hr;
1141 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1143 hr = get_node_type(Type, &node_type);
1144 if(FAILED(hr))
1145 return hr;
1147 TRACE("node_type %d\n", node_type);
1149 xml_name = xmlChar_from_wchar((WCHAR*)name);
1151 switch(node_type)
1153 case NODE_ELEMENT:
1154 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1155 *node = create_node(xmlnode);
1156 TRACE("created %p\n", xmlnode);
1157 break;
1158 case NODE_ATTRIBUTE:
1159 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1160 if(xmlnode)
1162 xmlnode->doc = get_doc( This );
1164 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1167 TRACE("created %p\n", xmlnode);
1168 break;
1170 default:
1171 FIXME("unhandled node type %d\n", node_type);
1172 break;
1175 HeapFree(GetProcessHeap(), 0, xml_name);
1177 if(xmlnode && *node)
1178 return S_OK;
1180 return E_FAIL;
1183 static HRESULT WINAPI domdoc_nodeFromID(
1184 IXMLDOMDocument2 *iface,
1185 BSTR idString,
1186 IXMLDOMNode** node )
1188 FIXME("\n");
1189 return E_NOTIMPL;
1192 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1194 domdoc *This = obj;
1195 xmlDocPtr xmldoc;
1197 xmldoc = doparse( ptr, len );
1198 if(xmldoc) {
1199 xmldoc->_private = 0;
1200 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1203 return S_OK;
1206 static HRESULT doread( domdoc *This, LPWSTR filename )
1208 bsc_t *bsc;
1209 HRESULT hr;
1211 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1212 if(FAILED(hr))
1213 return hr;
1215 if(This->bsc)
1216 detach_bsc(This->bsc);
1218 This->bsc = bsc;
1219 return S_OK;
1222 static HRESULT WINAPI domdoc_load(
1223 IXMLDOMDocument2 *iface,
1224 VARIANT xmlSource,
1225 VARIANT_BOOL* isSuccessful )
1227 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1228 LPWSTR filename = NULL;
1229 HRESULT hr = S_FALSE;
1230 IXMLDOMDocument2 *pNewDoc = NULL;
1231 IStream *pStream = NULL;
1232 xmlDocPtr xmldoc;
1234 TRACE("type %d\n", V_VT(&xmlSource) );
1236 *isSuccessful = VARIANT_FALSE;
1238 assert( This->node );
1240 attach_xmlnode(This->node, NULL);
1242 switch( V_VT(&xmlSource) )
1244 case VT_BSTR:
1245 filename = V_BSTR(&xmlSource);
1246 break;
1247 case VT_UNKNOWN:
1248 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1249 if(hr == S_OK)
1251 if(pNewDoc)
1253 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1254 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1255 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1257 *isSuccessful = VARIANT_TRUE;
1259 return S_OK;
1262 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1263 if(hr == S_OK)
1265 IPersistStream *pDocStream;
1266 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1267 if(hr == S_OK)
1269 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1270 IStream_Release(pStream);
1271 if(hr == S_OK)
1273 *isSuccessful = VARIANT_TRUE;
1275 TRACE("Using ID_IStream to load Document\n");
1276 return S_OK;
1278 else
1280 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1283 else
1285 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1288 else
1290 /* ISequentialStream */
1291 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1293 break;
1294 default:
1295 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1298 TRACE("filename (%s)\n", debugstr_w(filename));
1300 if ( filename )
1302 hr = doread( This, filename );
1304 if ( FAILED(hr) )
1305 This->error = E_FAIL;
1306 else
1308 hr = This->error = S_OK;
1309 *isSuccessful = VARIANT_TRUE;
1313 if(!filename || FAILED(hr)) {
1314 xmldoc = xmlNewDoc(NULL);
1315 xmldoc->_private = 0;
1316 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1317 hr = S_FALSE;
1320 TRACE("ret (%d)\n", hr);
1322 return hr;
1326 static HRESULT WINAPI domdoc_get_readyState(
1327 IXMLDOMDocument2 *iface,
1328 long* value )
1330 FIXME("\n");
1331 return E_NOTIMPL;
1335 static HRESULT WINAPI domdoc_get_parseError(
1336 IXMLDOMDocument2 *iface,
1337 IXMLDOMParseError** errorObj )
1339 BSTR error_string = NULL;
1340 static const WCHAR err[] = {'e','r','r','o','r',0};
1341 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1343 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1345 if(This->error)
1346 error_string = SysAllocString(err);
1348 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1349 if(!*errorObj) return E_OUTOFMEMORY;
1350 return S_OK;
1354 static HRESULT WINAPI domdoc_get_url(
1355 IXMLDOMDocument2 *iface,
1356 BSTR* urlString )
1358 FIXME("\n");
1359 return E_NOTIMPL;
1363 static HRESULT WINAPI domdoc_get_async(
1364 IXMLDOMDocument2 *iface,
1365 VARIANT_BOOL* isAsync )
1367 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1369 TRACE("%p <- %d\n", isAsync, This->async);
1370 *isAsync = This->async;
1371 return S_OK;
1375 static HRESULT WINAPI domdoc_put_async(
1376 IXMLDOMDocument2 *iface,
1377 VARIANT_BOOL isAsync )
1379 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1381 TRACE("%d\n", isAsync);
1382 This->async = isAsync;
1383 return S_OK;
1387 static HRESULT WINAPI domdoc_abort(
1388 IXMLDOMDocument2 *iface )
1390 FIXME("\n");
1391 return E_NOTIMPL;
1395 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1397 UINT len, blen = SysStringLen( bstr );
1398 LPSTR str;
1400 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1401 str = HeapAlloc( GetProcessHeap(), 0, len );
1402 if ( !str )
1403 return FALSE;
1404 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1405 *plen = len;
1406 *pstr = str;
1407 return TRUE;
1410 static HRESULT WINAPI domdoc_loadXML(
1411 IXMLDOMDocument2 *iface,
1412 BSTR bstrXML,
1413 VARIANT_BOOL* isSuccessful )
1415 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1416 xmlDocPtr xmldoc = NULL;
1417 char *str;
1418 int len;
1419 HRESULT hr = S_FALSE;
1421 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1423 assert ( This->node );
1425 attach_xmlnode( This->node, NULL );
1427 if ( isSuccessful )
1429 *isSuccessful = VARIANT_FALSE;
1431 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1433 xmldoc = doparse( str, len );
1434 HeapFree( GetProcessHeap(), 0, str );
1435 if ( !xmldoc )
1436 This->error = E_FAIL;
1437 else
1439 hr = This->error = S_OK;
1440 *isSuccessful = VARIANT_TRUE;
1444 if(!xmldoc)
1445 xmldoc = xmlNewDoc(NULL);
1447 xmldoc->_private = 0;
1448 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1450 return hr;
1454 static HRESULT WINAPI domdoc_save(
1455 IXMLDOMDocument2 *iface,
1456 VARIANT destination )
1458 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1459 HANDLE handle;
1460 xmlChar *mem, *p;
1461 int size;
1462 HRESULT ret = S_OK;
1463 DWORD written;
1465 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1466 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1468 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1470 FIXME("Unhandled vt %d\n", V_VT(&destination));
1471 return S_FALSE;
1474 if(V_VT(&destination) == VT_UNKNOWN)
1476 IUnknown *pUnk = V_UNKNOWN(&destination);
1477 IXMLDOMDocument *pDocument;
1479 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1480 if(ret == S_OK)
1482 BSTR bXML;
1483 VARIANT_BOOL bSuccessful;
1485 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1486 if(ret == S_OK)
1488 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1490 SysFreeString(bXML);
1493 IXMLDOMDocument_Release(pDocument);
1496 TRACE("ret %d\n", ret);
1498 return ret;
1501 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1502 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1503 if( handle == INVALID_HANDLE_VALUE )
1505 WARN("failed to create file\n");
1506 return S_FALSE;
1509 xmlDocDumpMemory(get_doc(This), &mem, &size);
1512 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1513 * MSXML adds XML declaration only for processing instruction nodes.
1514 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1516 p = mem;
1517 if(size > 2 && p[0] == '<' && p[1] == '?') {
1518 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1519 p++;
1520 p += 2;
1521 while(p < mem+size && isspace(*p))
1522 p++;
1523 size -= p-mem;
1526 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1528 WARN("write error\n");
1529 ret = S_FALSE;
1532 xmlFree(mem);
1533 CloseHandle(handle);
1534 return ret;
1537 static HRESULT WINAPI domdoc_get_validateOnParse(
1538 IXMLDOMDocument2 *iface,
1539 VARIANT_BOOL* isValidating )
1541 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1543 TRACE("%p <- %d\n", isValidating, This->validating);
1544 *isValidating = This->validating;
1545 return S_OK;
1549 static HRESULT WINAPI domdoc_put_validateOnParse(
1550 IXMLDOMDocument2 *iface,
1551 VARIANT_BOOL isValidating )
1553 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1555 TRACE("%d\n", isValidating);
1556 This->validating = isValidating;
1557 return S_OK;
1561 static HRESULT WINAPI domdoc_get_resolveExternals(
1562 IXMLDOMDocument2 *iface,
1563 VARIANT_BOOL* isResolving )
1565 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1567 TRACE("%p <- %d\n", isResolving, This->resolving);
1568 *isResolving = This->resolving;
1569 return S_OK;
1573 static HRESULT WINAPI domdoc_put_resolveExternals(
1574 IXMLDOMDocument2 *iface,
1575 VARIANT_BOOL isResolving )
1577 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1579 TRACE("%d\n", isResolving);
1580 This->resolving = isResolving;
1581 return S_OK;
1585 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1586 IXMLDOMDocument2 *iface,
1587 VARIANT_BOOL* isPreserving )
1589 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1591 TRACE("%p <- %d\n", isPreserving, This->preserving);
1592 *isPreserving = This->preserving;
1593 return S_OK;
1597 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1598 IXMLDOMDocument2 *iface,
1599 VARIANT_BOOL isPreserving )
1601 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1603 TRACE("%d\n", isPreserving);
1604 This->preserving = isPreserving;
1605 return S_OK;
1609 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1610 IXMLDOMDocument2 *iface,
1611 VARIANT readyStateChangeSink )
1613 FIXME("\n");
1614 return E_NOTIMPL;
1618 static HRESULT WINAPI domdoc_put_onDataAvailable(
1619 IXMLDOMDocument2 *iface,
1620 VARIANT onDataAvailableSink )
1622 FIXME("\n");
1623 return E_NOTIMPL;
1626 static HRESULT WINAPI domdoc_put_onTransformNode(
1627 IXMLDOMDocument2 *iface,
1628 VARIANT onTransformNodeSink )
1630 FIXME("\n");
1631 return E_NOTIMPL;
1634 static HRESULT WINAPI domdoc_get_namespaces(
1635 IXMLDOMDocument2* iface,
1636 IXMLDOMSchemaCollection** schemaCollection )
1638 FIXME("\n");
1639 return E_NOTIMPL;
1642 static HRESULT WINAPI domdoc_get_schemas(
1643 IXMLDOMDocument2* iface,
1644 VARIANT* var1 )
1646 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1647 HRESULT hr = S_FALSE;
1648 IXMLDOMSchemaCollection *cur_schema = This->schema;
1650 TRACE("(%p)->(%p)\n", This, var1);
1652 VariantInit(var1); /* Test shows we don't call VariantClear here */
1653 V_VT(var1) = VT_NULL;
1655 if(cur_schema)
1657 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1658 if(SUCCEEDED(hr))
1659 V_VT(var1) = VT_DISPATCH;
1661 return hr;
1664 static HRESULT WINAPI domdoc_putref_schemas(
1665 IXMLDOMDocument2* iface,
1666 VARIANT var1)
1668 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1669 HRESULT hr = E_FAIL;
1670 IXMLDOMSchemaCollection *new_schema = NULL;
1672 FIXME("(%p): semi-stub\n", This);
1673 switch(V_VT(&var1))
1675 case VT_UNKNOWN:
1676 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1677 break;
1679 case VT_DISPATCH:
1680 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1681 break;
1683 case VT_NULL:
1684 case VT_EMPTY:
1685 hr = S_OK;
1686 break;
1688 default:
1689 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1692 if(SUCCEEDED(hr))
1694 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1695 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1698 return hr;
1701 static HRESULT WINAPI domdoc_validate(
1702 IXMLDOMDocument2* iface,
1703 IXMLDOMParseError** err)
1705 FIXME("\n");
1706 return E_NOTIMPL;
1709 static HRESULT WINAPI domdoc_setProperty(
1710 IXMLDOMDocument2* iface,
1711 BSTR p,
1712 VARIANT var)
1714 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1716 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1718 VARIANT varStr;
1719 HRESULT hr;
1720 BSTR bstr;
1722 V_VT(&varStr) = VT_EMPTY;
1723 if (V_VT(&var) != VT_BSTR)
1725 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1726 return hr;
1727 bstr = V_BSTR(&varStr);
1729 else
1730 bstr = V_BSTR(&var);
1732 hr = S_OK;
1733 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1734 This->bUseXPath = TRUE;
1735 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1736 This->bUseXPath = FALSE;
1737 else
1738 hr = E_FAIL;
1740 VariantClear(&varStr);
1741 return hr;
1744 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1745 return E_FAIL;
1748 static HRESULT WINAPI domdoc_getProperty(
1749 IXMLDOMDocument2* iface,
1750 BSTR p,
1751 VARIANT* var)
1753 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1755 if (var == NULL)
1756 return E_INVALIDARG;
1757 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1759 V_VT(var) = VT_BSTR;
1760 if (This->bUseXPath)
1761 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1762 else
1763 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1764 return S_OK;
1767 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1768 return E_FAIL;
1771 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1773 domdoc_QueryInterface,
1774 domdoc_AddRef,
1775 domdoc_Release,
1776 domdoc_GetTypeInfoCount,
1777 domdoc_GetTypeInfo,
1778 domdoc_GetIDsOfNames,
1779 domdoc_Invoke,
1780 domdoc_get_nodeName,
1781 domdoc_get_nodeValue,
1782 domdoc_put_nodeValue,
1783 domdoc_get_nodeType,
1784 domdoc_get_parentNode,
1785 domdoc_get_childNodes,
1786 domdoc_get_firstChild,
1787 domdoc_get_lastChild,
1788 domdoc_get_previousSibling,
1789 domdoc_get_nextSibling,
1790 domdoc_get_attributes,
1791 domdoc_insertBefore,
1792 domdoc_replaceChild,
1793 domdoc_removeChild,
1794 domdoc_appendChild,
1795 domdoc_hasChildNodes,
1796 domdoc_get_ownerDocument,
1797 domdoc_cloneNode,
1798 domdoc_get_nodeTypeString,
1799 domdoc_get_text,
1800 domdoc_put_text,
1801 domdoc_get_specified,
1802 domdoc_get_definition,
1803 domdoc_get_nodeTypedValue,
1804 domdoc_put_nodeTypedValue,
1805 domdoc_get_dataType,
1806 domdoc_put_dataType,
1807 domdoc_get_xml,
1808 domdoc_transformNode,
1809 domdoc_selectNodes,
1810 domdoc_selectSingleNode,
1811 domdoc_get_parsed,
1812 domdoc_get_namespaceURI,
1813 domdoc_get_prefix,
1814 domdoc_get_baseName,
1815 domdoc_transformNodeToObject,
1816 domdoc_get_doctype,
1817 domdoc_get_implementation,
1818 domdoc_get_documentElement,
1819 domdoc_put_documentElement,
1820 domdoc_createElement,
1821 domdoc_createDocumentFragment,
1822 domdoc_createTextNode,
1823 domdoc_createComment,
1824 domdoc_createCDATASection,
1825 domdoc_createProcessingInstruction,
1826 domdoc_createAttribute,
1827 domdoc_createEntityReference,
1828 domdoc_getElementsByTagName,
1829 domdoc_createNode,
1830 domdoc_nodeFromID,
1831 domdoc_load,
1832 domdoc_get_readyState,
1833 domdoc_get_parseError,
1834 domdoc_get_url,
1835 domdoc_get_async,
1836 domdoc_put_async,
1837 domdoc_abort,
1838 domdoc_loadXML,
1839 domdoc_save,
1840 domdoc_get_validateOnParse,
1841 domdoc_put_validateOnParse,
1842 domdoc_get_resolveExternals,
1843 domdoc_put_resolveExternals,
1844 domdoc_get_preserveWhiteSpace,
1845 domdoc_put_preserveWhiteSpace,
1846 domdoc_put_onReadyStateChange,
1847 domdoc_put_onDataAvailable,
1848 domdoc_put_onTransformNode,
1849 domdoc_get_namespaces,
1850 domdoc_get_schemas,
1851 domdoc_putref_schemas,
1852 domdoc_validate,
1853 domdoc_setProperty,
1854 domdoc_getProperty
1857 /* xmldoc implementation of IObjectWithSite */
1858 static HRESULT WINAPI
1859 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
1861 domdoc *This = impl_from_IObjectWithSite(iface);
1862 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
1865 static ULONG WINAPI
1866 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
1868 domdoc *This = impl_from_IObjectWithSite(iface);
1869 return IXMLDocument_AddRef((IXMLDocument *)This);
1872 static ULONG WINAPI
1873 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
1875 domdoc *This = impl_from_IObjectWithSite(iface);
1876 return IXMLDocument_Release((IXMLDocument *)This);
1879 static HRESULT WINAPI
1880 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
1882 domdoc *This = impl_from_IObjectWithSite(iface);
1884 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
1886 if ( !This->site )
1887 return E_FAIL;
1889 return IUnknown_QueryInterface( This->site, iid, ppvSite );
1892 static HRESULT WINAPI
1893 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
1895 domdoc *This = impl_from_IObjectWithSite(iface);
1897 TRACE("%p %p\n", iface, punk);
1899 if(!punk)
1901 if(This->site)
1903 IUnknown_Release( This->site );
1904 This->site = NULL;
1907 return S_OK;
1910 if ( punk )
1911 IUnknown_AddRef( punk );
1913 if(This->site)
1914 IUnknown_Release( This->site );
1916 This->site = punk;
1918 return S_OK;
1921 static const IObjectWithSiteVtbl domdocObjectSite =
1923 xmldoc_ObjectWithSite_QueryInterface,
1924 xmldoc_ObjectWithSite_AddRef,
1925 xmldoc_ObjectWithSite_Release,
1926 xmldoc_SetSite,
1927 xmldoc_GetSite,
1930 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1932 domdoc *This = impl_from_IObjectSafety(iface);
1933 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
1936 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
1938 domdoc *This = impl_from_IObjectSafety(iface);
1939 return IXMLDocument_AddRef((IXMLDocument *)This);
1942 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
1944 domdoc *This = impl_from_IObjectSafety(iface);
1945 return IXMLDocument_Release((IXMLDocument *)This);
1948 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
1950 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1951 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1953 domdoc *This = impl_from_IObjectSafety(iface);
1955 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
1957 if(!pdwSupportedOptions || !pdwEnabledOptions)
1958 return E_POINTER;
1960 *pdwSupportedOptions = SUPPORTED_OPTIONS;
1961 *pdwEnabledOptions = This->safeopt;
1963 return S_OK;
1966 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1967 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1969 domdoc *This = impl_from_IObjectSafety(iface);
1971 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
1973 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
1974 return E_FAIL;
1976 This->safeopt = dwEnabledOptions & dwEnabledOptions;
1977 return S_OK;
1980 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
1981 xmldoc_Safety_QueryInterface,
1982 xmldoc_Safety_AddRef,
1983 xmldoc_Safety_Release,
1984 xmldoc_Safety_GetInterfaceSafetyOptions,
1985 xmldoc_Safety_SetInterfaceSafetyOptions
1989 static const tid_t domdoc_iface_tids[] = {
1990 IXMLDOMNode_tid,
1991 IXMLDOMDocument_tid,
1992 IXMLDOMDocument2_tid,
1995 static dispex_static_data_t domdoc_dispex = {
1996 NULL,
1997 IXMLDOMDocument2_tid,
1998 NULL,
1999 domdoc_iface_tids
2002 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2004 domdoc *doc;
2005 HRESULT hr;
2007 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2008 if( !doc )
2009 return E_OUTOFMEMORY;
2011 doc->lpVtbl = &domdoc_vtbl;
2012 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2013 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2014 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2015 doc->ref = 1;
2016 doc->async = 0;
2017 doc->validating = 0;
2018 doc->resolving = 0;
2019 doc->preserving = 0;
2020 doc->bUseXPath = FALSE;
2021 doc->error = S_OK;
2022 doc->schema = NULL;
2023 doc->stream = NULL;
2024 doc->site = NULL;
2025 doc->safeopt = 0;
2026 doc->bsc = NULL;
2028 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2029 if(!doc->node_unk)
2031 HeapFree(GetProcessHeap(), 0, doc);
2032 return E_FAIL;
2035 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2036 if(FAILED(hr))
2038 IUnknown_Release(doc->node_unk);
2039 HeapFree( GetProcessHeap(), 0, doc );
2040 return E_FAIL;
2043 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2045 /* The ref on doc->node is actually looped back into this object, so release it */
2046 IXMLDOMNode_Release(doc->node);
2048 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2050 TRACE("returning iface %p\n", *document);
2051 return S_OK;
2054 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2056 xmlDocPtr xmldoc;
2057 HRESULT hr;
2059 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2061 xmldoc = xmlNewDoc(NULL);
2062 if(!xmldoc)
2063 return E_OUTOFMEMORY;
2065 xmldoc->_private = 0;
2067 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2068 if(FAILED(hr))
2069 xmlFreeDoc(xmldoc);
2071 return hr;
2074 IUnknown* create_domdoc( xmlNodePtr document )
2076 HRESULT hr;
2077 LPVOID pObj = NULL;
2079 TRACE("(%p)\n", document);
2081 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2082 if (FAILED(hr))
2083 return NULL;
2085 return (IUnknown*)pObj;
2088 #else
2090 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2092 MESSAGE("This program tried to use a DOMDocument object, but\n"
2093 "libxml2 support was not present at compile time.\n");
2094 return E_NOTIMPL;
2097 #endif