push 6495605bb529da27066f1c178d57d902552737a0
[wine/hacks.git] / dlls / msxml3 / domdoc.c
blob61f01f1fdb754fc663974aedb953a7a7b44a8915
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"
40 #include "wine/debug.h"
42 #include "msxml_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
46 #ifdef HAVE_LIBXML2
48 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};
49 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
50 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
52 typedef struct _domdoc
54 const struct IXMLDOMDocument2Vtbl *lpVtbl;
55 const struct IPersistStreamVtbl *lpvtblIPersistStream;
56 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
57 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
58 LONG ref;
59 VARIANT_BOOL async;
60 VARIANT_BOOL validating;
61 VARIANT_BOOL resolving;
62 VARIANT_BOOL preserving;
63 BOOL bUseXPath;
64 IUnknown *node_unk;
65 IXMLDOMNode *node;
66 IXMLDOMSchemaCollection *schema;
67 bsc_t *bsc;
68 HRESULT error;
70 /* IPersistStream */
71 IStream *stream;
73 /* IObjectWithSite*/
74 IUnknown *site;
76 /* IObjectSafety */
77 DWORD safeopt;
78 } domdoc;
80 static xmlDocPtr doparse( char *ptr, int len )
82 #ifdef HAVE_XMLREADMEMORY
84 * use xmlReadMemory if possible so we can suppress
85 * writing errors to stderr
87 return xmlReadMemory( ptr, len, NULL, NULL,
88 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
89 #else
90 return xmlParseMemory( ptr, len );
91 #endif
94 LONG xmldoc_add_ref(xmlDocPtr doc)
96 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
97 TRACE("%d\n", ref);
98 return ref;
101 LONG xmldoc_release(xmlDocPtr doc)
103 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
104 TRACE("%d\n", ref);
105 if(ref == 0)
107 TRACE("freeing docptr %p\n", doc);
108 xmlFreeDoc(doc);
111 return ref;
114 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
116 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
119 static inline xmlDocPtr get_doc( domdoc *This )
121 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
124 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
126 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
129 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
131 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
134 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
136 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
140 /************************************************************************
141 * xmldoc implementation of IPersistStream.
143 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
144 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
146 domdoc *this = impl_from_IPersistStream(iface);
147 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
150 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
151 IPersistStream *iface)
153 domdoc *this = impl_from_IPersistStream(iface);
154 return IXMLDocument_AddRef((IXMLDocument *)this);
157 static ULONG WINAPI xmldoc_IPersistStream_Release(
158 IPersistStream *iface)
160 domdoc *this = impl_from_IPersistStream(iface);
161 return IXMLDocument_Release((IXMLDocument *)this);
164 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
165 IPersistStream *iface, CLSID *classid)
167 TRACE("(%p,%p): stub!\n", iface, classid);
169 if(!classid)
170 return E_POINTER;
172 *classid = CLSID_DOMDocument2;
174 return S_OK;
177 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
178 IPersistStream *iface)
180 domdoc *This = impl_from_IPersistStream(iface);
182 FIXME("(%p->%p): stub!\n", iface, This);
184 return S_FALSE;
187 static HRESULT WINAPI xmldoc_IPersistStream_Load(
188 IPersistStream *iface, LPSTREAM pStm)
190 domdoc *This = impl_from_IPersistStream(iface);
191 HRESULT hr;
192 HGLOBAL hglobal;
193 DWORD read, written, len;
194 BYTE buf[4096];
195 char *ptr;
196 xmlDocPtr xmldoc = NULL;
198 TRACE("(%p, %p)\n", iface, pStm);
200 if (!pStm)
201 return E_INVALIDARG;
203 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
204 if (FAILED(hr))
205 return hr;
209 IStream_Read(pStm, buf, sizeof(buf), &read);
210 hr = IStream_Write(This->stream, buf, read, &written);
211 } while(SUCCEEDED(hr) && written != 0 && read != 0);
213 if (FAILED(hr))
215 ERR("Failed to copy stream\n");
216 return hr;
219 hr = GetHGlobalFromStream(This->stream, &hglobal);
220 if (FAILED(hr))
221 return hr;
223 len = GlobalSize(hglobal);
224 ptr = GlobalLock(hglobal);
225 if (len != 0)
226 xmldoc = parse_xml(ptr, len);
227 GlobalUnlock(hglobal);
229 if (!xmldoc)
231 ERR("Failed to parse xml\n");
232 return E_FAIL;
235 attach_xmlnode( This->node, (xmlNodePtr)xmldoc );
237 return S_OK;
240 static HRESULT WINAPI xmldoc_IPersistStream_Save(
241 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
243 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
244 return E_NOTIMPL;
247 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
248 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
250 TRACE("(%p, %p): stub!\n", iface, pcbSize);
251 return E_NOTIMPL;
254 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
256 xmldoc_IPersistStream_QueryInterface,
257 xmldoc_IPersistStream_AddRef,
258 xmldoc_IPersistStream_Release,
259 xmldoc_IPersistStream_GetClassID,
260 xmldoc_IPersistStream_IsDirty,
261 xmldoc_IPersistStream_Load,
262 xmldoc_IPersistStream_Save,
263 xmldoc_IPersistStream_GetSizeMax,
266 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
268 domdoc *This = impl_from_IXMLDOMDocument2( iface );
270 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
272 *ppvObject = NULL;
274 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
275 IsEqualGUID( riid, &IID_IDispatch ) ||
276 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
277 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
279 *ppvObject = iface;
281 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
283 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
285 else if (IsEqualGUID(&IID_IPersistStream, riid))
287 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
289 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
291 *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite);
293 else if(IsEqualGUID(&IID_IRunnableObject, riid))
295 TRACE("IID_IRunnableObject not supported returning NULL\n");
296 return E_NOINTERFACE;
298 else
300 FIXME("interface %s not implemented\n", debugstr_guid(riid));
301 return E_NOINTERFACE;
304 IXMLDOMDocument_AddRef( iface );
306 return S_OK;
310 static ULONG WINAPI domdoc_AddRef(
311 IXMLDOMDocument2 *iface )
313 domdoc *This = impl_from_IXMLDOMDocument2( iface );
314 TRACE("%p\n", This );
315 return InterlockedIncrement( &This->ref );
319 static ULONG WINAPI domdoc_Release(
320 IXMLDOMDocument2 *iface )
322 domdoc *This = impl_from_IXMLDOMDocument2( iface );
323 LONG ref;
325 TRACE("%p\n", This );
327 ref = InterlockedDecrement( &This->ref );
328 if ( ref == 0 )
330 if(This->bsc)
331 detach_bsc(This->bsc);
333 if (This->site)
334 IUnknown_Release( This->site );
335 IUnknown_Release( This->node_unk );
336 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
337 if (This->stream) IStream_Release(This->stream);
338 HeapFree( GetProcessHeap(), 0, This );
341 return ref;
344 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
346 domdoc *This = impl_from_IXMLDOMDocument2( iface );
348 TRACE("(%p)->(%p)\n", This, pctinfo);
350 *pctinfo = 1;
352 return S_OK;
355 static HRESULT WINAPI domdoc_GetTypeInfo(
356 IXMLDOMDocument2 *iface,
357 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
359 domdoc *This = impl_from_IXMLDOMDocument2( iface );
360 HRESULT hr;
362 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
364 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
366 return hr;
369 static HRESULT WINAPI domdoc_GetIDsOfNames(
370 IXMLDOMDocument2 *iface,
371 REFIID riid,
372 LPOLESTR* rgszNames,
373 UINT cNames,
374 LCID lcid,
375 DISPID* rgDispId)
377 domdoc *This = impl_from_IXMLDOMDocument2( iface );
378 ITypeInfo *typeinfo;
379 HRESULT hr;
381 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
382 lcid, rgDispId);
384 if(!rgszNames || cNames == 0 || !rgDispId)
385 return E_INVALIDARG;
387 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
388 if(SUCCEEDED(hr))
390 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
391 ITypeInfo_Release(typeinfo);
394 return hr;
398 static HRESULT WINAPI domdoc_Invoke(
399 IXMLDOMDocument2 *iface,
400 DISPID dispIdMember,
401 REFIID riid,
402 LCID lcid,
403 WORD wFlags,
404 DISPPARAMS* pDispParams,
405 VARIANT* pVarResult,
406 EXCEPINFO* pExcepInfo,
407 UINT* puArgErr)
409 domdoc *This = impl_from_IXMLDOMDocument2( iface );
410 ITypeInfo *typeinfo;
411 HRESULT hr;
413 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
414 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
416 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
417 if(SUCCEEDED(hr))
419 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
420 pVarResult, pExcepInfo, puArgErr);
421 ITypeInfo_Release(typeinfo);
424 return hr;
428 static HRESULT WINAPI domdoc_get_nodeName(
429 IXMLDOMDocument2 *iface,
430 BSTR* name )
432 domdoc *This = impl_from_IXMLDOMDocument2( iface );
433 return IXMLDOMNode_get_nodeName( This->node, name );
437 static HRESULT WINAPI domdoc_get_nodeValue(
438 IXMLDOMDocument2 *iface,
439 VARIANT* value )
441 domdoc *This = impl_from_IXMLDOMDocument2( iface );
442 return IXMLDOMNode_get_nodeValue( This->node, value );
446 static HRESULT WINAPI domdoc_put_nodeValue(
447 IXMLDOMDocument2 *iface,
448 VARIANT value)
450 domdoc *This = impl_from_IXMLDOMDocument2( iface );
451 return IXMLDOMNode_put_nodeValue( This->node, value );
455 static HRESULT WINAPI domdoc_get_nodeType(
456 IXMLDOMDocument2 *iface,
457 DOMNodeType* type )
459 domdoc *This = impl_from_IXMLDOMDocument2( iface );
460 return IXMLDOMNode_get_nodeType( This->node, type );
464 static HRESULT WINAPI domdoc_get_parentNode(
465 IXMLDOMDocument2 *iface,
466 IXMLDOMNode** parent )
468 domdoc *This = impl_from_IXMLDOMDocument2( iface );
469 return IXMLDOMNode_get_parentNode( This->node, parent );
473 static HRESULT WINAPI domdoc_get_childNodes(
474 IXMLDOMDocument2 *iface,
475 IXMLDOMNodeList** childList )
477 domdoc *This = impl_from_IXMLDOMDocument2( iface );
478 return IXMLDOMNode_get_childNodes( This->node, childList );
482 static HRESULT WINAPI domdoc_get_firstChild(
483 IXMLDOMDocument2 *iface,
484 IXMLDOMNode** firstChild )
486 domdoc *This = impl_from_IXMLDOMDocument2( iface );
487 return IXMLDOMNode_get_firstChild( This->node, firstChild );
491 static HRESULT WINAPI domdoc_get_lastChild(
492 IXMLDOMDocument2 *iface,
493 IXMLDOMNode** lastChild )
495 domdoc *This = impl_from_IXMLDOMDocument2( iface );
496 return IXMLDOMNode_get_lastChild( This->node, lastChild );
500 static HRESULT WINAPI domdoc_get_previousSibling(
501 IXMLDOMDocument2 *iface,
502 IXMLDOMNode** previousSibling )
504 domdoc *This = impl_from_IXMLDOMDocument2( iface );
505 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
509 static HRESULT WINAPI domdoc_get_nextSibling(
510 IXMLDOMDocument2 *iface,
511 IXMLDOMNode** nextSibling )
513 domdoc *This = impl_from_IXMLDOMDocument2( iface );
514 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
518 static HRESULT WINAPI domdoc_get_attributes(
519 IXMLDOMDocument2 *iface,
520 IXMLDOMNamedNodeMap** attributeMap )
522 domdoc *This = impl_from_IXMLDOMDocument2( iface );
523 return IXMLDOMNode_get_attributes( This->node, attributeMap );
527 static HRESULT WINAPI domdoc_insertBefore(
528 IXMLDOMDocument2 *iface,
529 IXMLDOMNode* newChild,
530 VARIANT refChild,
531 IXMLDOMNode** outNewChild )
533 domdoc *This = impl_from_IXMLDOMDocument2( iface );
534 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
538 static HRESULT WINAPI domdoc_replaceChild(
539 IXMLDOMDocument2 *iface,
540 IXMLDOMNode* newChild,
541 IXMLDOMNode* oldChild,
542 IXMLDOMNode** outOldChild)
544 domdoc *This = impl_from_IXMLDOMDocument2( iface );
545 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
549 static HRESULT WINAPI domdoc_removeChild(
550 IXMLDOMDocument2 *iface,
551 IXMLDOMNode* childNode,
552 IXMLDOMNode** oldChild)
554 domdoc *This = impl_from_IXMLDOMDocument2( iface );
555 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
559 static HRESULT WINAPI domdoc_appendChild(
560 IXMLDOMDocument2 *iface,
561 IXMLDOMNode* newChild,
562 IXMLDOMNode** outNewChild)
564 domdoc *This = impl_from_IXMLDOMDocument2( iface );
565 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
569 static HRESULT WINAPI domdoc_hasChildNodes(
570 IXMLDOMDocument2 *iface,
571 VARIANT_BOOL* hasChild)
573 domdoc *This = impl_from_IXMLDOMDocument2( iface );
574 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
578 static HRESULT WINAPI domdoc_get_ownerDocument(
579 IXMLDOMDocument2 *iface,
580 IXMLDOMDocument** DOMDocument)
582 domdoc *This = impl_from_IXMLDOMDocument2( iface );
583 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
587 static HRESULT WINAPI domdoc_cloneNode(
588 IXMLDOMDocument2 *iface,
589 VARIANT_BOOL deep,
590 IXMLDOMNode** cloneRoot)
592 domdoc *This = impl_from_IXMLDOMDocument2( iface );
593 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
597 static HRESULT WINAPI domdoc_get_nodeTypeString(
598 IXMLDOMDocument2 *iface,
599 BSTR* nodeType )
601 domdoc *This = impl_from_IXMLDOMDocument2( iface );
602 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
606 static HRESULT WINAPI domdoc_get_text(
607 IXMLDOMDocument2 *iface,
608 BSTR* text )
610 domdoc *This = impl_from_IXMLDOMDocument2( iface );
611 return IXMLDOMNode_get_text( This->node, text );
615 static HRESULT WINAPI domdoc_put_text(
616 IXMLDOMDocument2 *iface,
617 BSTR text )
619 domdoc *This = impl_from_IXMLDOMDocument2( iface );
620 return IXMLDOMNode_put_text( This->node, text );
624 static HRESULT WINAPI domdoc_get_specified(
625 IXMLDOMDocument2 *iface,
626 VARIANT_BOOL* isSpecified )
628 domdoc *This = impl_from_IXMLDOMDocument2( iface );
629 return IXMLDOMNode_get_specified( This->node, isSpecified );
633 static HRESULT WINAPI domdoc_get_definition(
634 IXMLDOMDocument2 *iface,
635 IXMLDOMNode** definitionNode )
637 domdoc *This = impl_from_IXMLDOMDocument2( iface );
638 return IXMLDOMNode_get_definition( This->node, definitionNode );
642 static HRESULT WINAPI domdoc_get_nodeTypedValue(
643 IXMLDOMDocument2 *iface,
644 VARIANT* typedValue )
646 domdoc *This = impl_from_IXMLDOMDocument2( iface );
647 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
650 static HRESULT WINAPI domdoc_put_nodeTypedValue(
651 IXMLDOMDocument2 *iface,
652 VARIANT typedValue )
654 domdoc *This = impl_from_IXMLDOMDocument2( iface );
655 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
659 static HRESULT WINAPI domdoc_get_dataType(
660 IXMLDOMDocument2 *iface,
661 VARIANT* dataTypeName )
663 domdoc *This = impl_from_IXMLDOMDocument2( iface );
664 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
668 static HRESULT WINAPI domdoc_put_dataType(
669 IXMLDOMDocument2 *iface,
670 BSTR dataTypeName )
672 domdoc *This = impl_from_IXMLDOMDocument2( iface );
673 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
677 static HRESULT WINAPI domdoc_get_xml(
678 IXMLDOMDocument2 *iface,
679 BSTR* xmlString )
681 domdoc *This = impl_from_IXMLDOMDocument2( iface );
682 return IXMLDOMNode_get_xml( This->node, xmlString );
686 static HRESULT WINAPI domdoc_transformNode(
687 IXMLDOMDocument2 *iface,
688 IXMLDOMNode* styleSheet,
689 BSTR* xmlString )
691 domdoc *This = impl_from_IXMLDOMDocument2( iface );
692 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
696 static HRESULT WINAPI domdoc_selectNodes(
697 IXMLDOMDocument2 *iface,
698 BSTR queryString,
699 IXMLDOMNodeList** resultList )
701 domdoc *This = impl_from_IXMLDOMDocument2( iface );
702 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
706 static HRESULT WINAPI domdoc_selectSingleNode(
707 IXMLDOMDocument2 *iface,
708 BSTR queryString,
709 IXMLDOMNode** resultNode )
711 domdoc *This = impl_from_IXMLDOMDocument2( iface );
712 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
716 static HRESULT WINAPI domdoc_get_parsed(
717 IXMLDOMDocument2 *iface,
718 VARIANT_BOOL* isParsed )
720 domdoc *This = impl_from_IXMLDOMDocument2( iface );
721 return IXMLDOMNode_get_parsed( This->node, isParsed );
725 static HRESULT WINAPI domdoc_get_namespaceURI(
726 IXMLDOMDocument2 *iface,
727 BSTR* namespaceURI )
729 domdoc *This = impl_from_IXMLDOMDocument2( iface );
730 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
734 static HRESULT WINAPI domdoc_get_prefix(
735 IXMLDOMDocument2 *iface,
736 BSTR* prefixString )
738 domdoc *This = impl_from_IXMLDOMDocument2( iface );
739 return IXMLDOMNode_get_prefix( This->node, prefixString );
743 static HRESULT WINAPI domdoc_get_baseName(
744 IXMLDOMDocument2 *iface,
745 BSTR* nameString )
747 domdoc *This = impl_from_IXMLDOMDocument2( iface );
748 return IXMLDOMNode_get_baseName( This->node, nameString );
752 static HRESULT WINAPI domdoc_transformNodeToObject(
753 IXMLDOMDocument2 *iface,
754 IXMLDOMNode* stylesheet,
755 VARIANT outputObject)
757 domdoc *This = impl_from_IXMLDOMDocument2( iface );
758 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
762 static HRESULT WINAPI domdoc_get_doctype(
763 IXMLDOMDocument2 *iface,
764 IXMLDOMDocumentType** documentType )
766 FIXME("\n");
767 return E_NOTIMPL;
771 static HRESULT WINAPI domdoc_get_implementation(
772 IXMLDOMDocument2 *iface,
773 IXMLDOMImplementation** impl )
775 if(!impl)
776 return E_INVALIDARG;
778 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
780 return S_OK;
783 static HRESULT WINAPI domdoc_get_documentElement(
784 IXMLDOMDocument2 *iface,
785 IXMLDOMElement** DOMElement )
787 domdoc *This = impl_from_IXMLDOMDocument2( iface );
788 xmlDocPtr xmldoc = NULL;
789 xmlNodePtr root = NULL;
790 IXMLDOMNode *element_node;
791 HRESULT hr;
793 TRACE("%p %p\n", This, This->node);
795 if(!DOMElement)
796 return E_INVALIDARG;
798 *DOMElement = NULL;
800 xmldoc = get_doc( This );
802 root = xmlDocGetRootElement( xmldoc );
803 if ( !root )
804 return S_FALSE;
806 element_node = create_node( root );
807 if(!element_node) return S_FALSE;
809 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
810 IXMLDOMNode_Release(element_node);
812 return hr;
816 static HRESULT WINAPI domdoc_put_documentElement(
817 IXMLDOMDocument2 *iface,
818 IXMLDOMElement* DOMElement )
820 domdoc *This = impl_from_IXMLDOMDocument2( iface );
821 IXMLDOMNode *elementNode;
822 xmlnode *xmlNode;
823 HRESULT hr;
825 TRACE("(%p)->(%p)\n", This, DOMElement);
827 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
828 if(FAILED(hr))
829 return hr;
831 xmlNode = impl_from_IXMLDOMNode( elementNode );
832 xmlDocSetRootElement( get_doc(This), xmlNode->node);
833 IXMLDOMNode_Release( elementNode );
835 return S_OK;
839 static HRESULT WINAPI domdoc_createElement(
840 IXMLDOMDocument2 *iface,
841 BSTR tagname,
842 IXMLDOMElement** element )
844 xmlNodePtr xmlnode;
845 domdoc *This = impl_from_IXMLDOMDocument2( iface );
846 xmlChar *xml_name;
847 IUnknown *elem_unk;
848 HRESULT hr;
850 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
852 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
853 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
855 TRACE("created xmlptr %p\n", xmlnode);
856 elem_unk = create_element(xmlnode, NULL);
857 HeapFree(GetProcessHeap(), 0, xml_name);
859 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
860 IUnknown_Release(elem_unk);
861 TRACE("returning %p\n", *element);
862 return hr;
866 static HRESULT WINAPI domdoc_createDocumentFragment(
867 IXMLDOMDocument2 *iface,
868 IXMLDOMDocumentFragment** docFrag )
870 domdoc *This = impl_from_IXMLDOMDocument2( iface );
871 xmlNodePtr xmlnode;
873 TRACE("%p\n", iface);
875 if(!docFrag)
876 return E_INVALIDARG;
878 *docFrag = NULL;
880 xmlnode = xmlNewDocFragment(get_doc( This ) );
882 if(!xmlnode)
883 return E_FAIL;
885 xmlnode->doc = get_doc( This );
887 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
889 return S_OK;
893 static HRESULT WINAPI domdoc_createTextNode(
894 IXMLDOMDocument2 *iface,
895 BSTR data,
896 IXMLDOMText** text )
898 domdoc *This = impl_from_IXMLDOMDocument2( iface );
899 xmlNodePtr xmlnode;
900 xmlChar *xml_content;
902 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
904 if(!text)
905 return E_INVALIDARG;
907 *text = NULL;
909 xml_content = xmlChar_from_wchar((WCHAR*)data);
910 xmlnode = xmlNewText(xml_content);
911 HeapFree(GetProcessHeap(), 0, xml_content);
913 if(!xmlnode)
914 return E_FAIL;
916 xmlnode->doc = get_doc( This );
918 *text = (IXMLDOMText*)create_text(xmlnode);
920 return S_OK;
924 static HRESULT WINAPI domdoc_createComment(
925 IXMLDOMDocument2 *iface,
926 BSTR data,
927 IXMLDOMComment** comment )
929 domdoc *This = impl_from_IXMLDOMDocument2( iface );
930 xmlNodePtr xmlnode;
931 xmlChar *xml_content;
933 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
935 if(!comment)
936 return E_INVALIDARG;
938 *comment = NULL;
940 xml_content = xmlChar_from_wchar((WCHAR*)data);
941 xmlnode = xmlNewComment(xml_content);
942 HeapFree(GetProcessHeap(), 0, xml_content);
944 if(!xmlnode)
945 return E_FAIL;
947 xmlnode->doc = get_doc( This );
949 *comment = (IXMLDOMComment*)create_comment(xmlnode);
951 return S_OK;
955 static HRESULT WINAPI domdoc_createCDATASection(
956 IXMLDOMDocument2 *iface,
957 BSTR data,
958 IXMLDOMCDATASection** cdata )
960 domdoc *This = impl_from_IXMLDOMDocument2( iface );
961 xmlNodePtr xmlnode;
962 xmlChar *xml_content;
964 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
966 if(!cdata)
967 return E_INVALIDARG;
969 *cdata = NULL;
971 xml_content = xmlChar_from_wchar((WCHAR*)data);
972 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
973 HeapFree(GetProcessHeap(), 0, xml_content);
975 if(!xmlnode)
976 return E_FAIL;
978 xmlnode->doc = get_doc( This );
980 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
982 return S_OK;
986 static HRESULT WINAPI domdoc_createProcessingInstruction(
987 IXMLDOMDocument2 *iface,
988 BSTR target,
989 BSTR data,
990 IXMLDOMProcessingInstruction** pi )
992 #ifdef HAVE_XMLNEWDOCPI
993 xmlNodePtr xmlnode;
994 domdoc *This = impl_from_IXMLDOMDocument2( iface );
995 xmlChar *xml_target, *xml_content;
997 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
999 if(!pi)
1000 return E_INVALIDARG;
1002 if(!target || lstrlenW(target) == 0)
1003 return E_FAIL;
1005 xml_target = xmlChar_from_wchar((WCHAR*)target);
1006 xml_content = xmlChar_from_wchar((WCHAR*)data);
1008 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1009 TRACE("created xmlptr %p\n", xmlnode);
1010 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1012 HeapFree(GetProcessHeap(), 0, xml_content);
1013 HeapFree(GetProcessHeap(), 0, xml_target);
1015 return S_OK;
1016 #else
1017 FIXME("Libxml 2.6.15 or greater required.\n");
1018 return E_NOTIMPL;
1019 #endif
1023 static HRESULT WINAPI domdoc_createAttribute(
1024 IXMLDOMDocument2 *iface,
1025 BSTR name,
1026 IXMLDOMAttribute** attribute )
1028 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1029 xmlNodePtr xmlnode;
1030 xmlChar *xml_name;
1032 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1034 if(!attribute)
1035 return E_INVALIDARG;
1037 *attribute = NULL;
1039 xml_name = xmlChar_from_wchar((WCHAR*)name);
1040 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1041 HeapFree(GetProcessHeap(), 0, xml_name);
1043 if(!xmlnode)
1044 return E_FAIL;
1046 xmlnode->doc = get_doc( This );
1048 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1050 return S_OK;
1054 static HRESULT WINAPI domdoc_createEntityReference(
1055 IXMLDOMDocument2 *iface,
1056 BSTR name,
1057 IXMLDOMEntityReference** entityRef )
1059 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1060 xmlNodePtr xmlnode;
1061 xmlChar *xml_name;
1063 TRACE("%p\n", iface);
1065 if(!entityRef)
1066 return E_INVALIDARG;
1068 *entityRef = NULL;
1070 xml_name = xmlChar_from_wchar((WCHAR*)name);
1071 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1072 HeapFree(GetProcessHeap(), 0, xml_name);
1074 if(!xmlnode)
1075 return E_FAIL;
1077 xmlnode->doc = get_doc( This );
1079 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1081 return S_OK;
1085 static HRESULT WINAPI domdoc_getElementsByTagName(
1086 IXMLDOMDocument2 *iface,
1087 BSTR tagName,
1088 IXMLDOMNodeList** resultList )
1090 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1091 LPWSTR szPattern;
1092 HRESULT hr;
1093 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1095 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1096 szPattern[0] = szPattern[1] = '/';
1097 lstrcpyW(szPattern + 2, tagName);
1099 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1100 HeapFree(GetProcessHeap(), 0, szPattern);
1102 return hr;
1105 static DOMNodeType get_node_type(VARIANT Type)
1107 if(V_VT(&Type) == VT_I4)
1108 return V_I4(&Type);
1110 FIXME("Unsupported variant type %x\n", V_VT(&Type));
1111 return 0;
1114 static HRESULT WINAPI domdoc_createNode(
1115 IXMLDOMDocument2 *iface,
1116 VARIANT Type,
1117 BSTR name,
1118 BSTR namespaceURI,
1119 IXMLDOMNode** node )
1121 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1122 DOMNodeType node_type;
1123 xmlNodePtr xmlnode = NULL;
1124 xmlChar *xml_name;
1126 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1128 node_type = get_node_type(Type);
1129 TRACE("node_type %d\n", node_type);
1131 xml_name = xmlChar_from_wchar((WCHAR*)name);
1133 switch(node_type)
1135 case NODE_ELEMENT:
1136 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1137 *node = create_node(xmlnode);
1138 TRACE("created %p\n", xmlnode);
1139 break;
1140 case NODE_ATTRIBUTE:
1141 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1142 if(xmlnode)
1144 xmlnode->doc = get_doc( This );
1146 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1149 TRACE("created %p\n", xmlnode);
1150 break;
1152 default:
1153 FIXME("unhandled node type %d\n", node_type);
1154 break;
1157 HeapFree(GetProcessHeap(), 0, xml_name);
1159 if(xmlnode && *node)
1160 return S_OK;
1162 return E_FAIL;
1165 static HRESULT WINAPI domdoc_nodeFromID(
1166 IXMLDOMDocument2 *iface,
1167 BSTR idString,
1168 IXMLDOMNode** node )
1170 FIXME("\n");
1171 return E_NOTIMPL;
1174 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1176 domdoc *This = obj;
1177 xmlDocPtr xmldoc;
1179 xmldoc = doparse( ptr, len );
1180 if(xmldoc) {
1181 xmldoc->_private = 0;
1182 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1185 return S_OK;
1188 static HRESULT doread( domdoc *This, LPWSTR filename )
1190 bsc_t *bsc;
1191 HRESULT hr;
1193 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1194 if(FAILED(hr))
1195 return hr;
1197 if(This->bsc)
1198 detach_bsc(This->bsc);
1200 This->bsc = bsc;
1201 return S_OK;
1204 static HRESULT WINAPI domdoc_load(
1205 IXMLDOMDocument2 *iface,
1206 VARIANT xmlSource,
1207 VARIANT_BOOL* isSuccessful )
1209 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1210 LPWSTR filename = NULL;
1211 HRESULT hr = S_FALSE;
1212 IXMLDOMDocument2 *pNewDoc = NULL;
1213 IStream *pStream = NULL;
1214 xmlDocPtr xmldoc;
1216 TRACE("type %d\n", V_VT(&xmlSource) );
1218 *isSuccessful = VARIANT_FALSE;
1220 assert( This->node );
1222 attach_xmlnode(This->node, NULL);
1224 switch( V_VT(&xmlSource) )
1226 case VT_BSTR:
1227 filename = V_BSTR(&xmlSource);
1228 break;
1229 case VT_UNKNOWN:
1230 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1231 if(hr == S_OK)
1233 if(pNewDoc)
1235 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1236 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1237 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1239 *isSuccessful = VARIANT_TRUE;
1241 return S_OK;
1244 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1245 if(hr == S_OK)
1247 IPersistStream *pDocStream;
1248 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1249 if(hr == S_OK)
1251 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1252 IStream_Release(pStream);
1253 if(hr == S_OK)
1255 *isSuccessful = VARIANT_TRUE;
1257 TRACE("Using ID_IStream to load Document\n");
1258 return S_OK;
1260 else
1262 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1265 else
1267 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1270 else
1272 /* ISequentialStream */
1273 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1275 break;
1276 default:
1277 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1280 TRACE("filename (%s)\n", debugstr_w(filename));
1282 if ( filename )
1284 hr = doread( This, filename );
1286 if ( FAILED(hr) )
1287 This->error = E_FAIL;
1288 else
1290 hr = This->error = S_OK;
1291 *isSuccessful = VARIANT_TRUE;
1295 if(!filename || FAILED(hr)) {
1296 xmldoc = xmlNewDoc(NULL);
1297 xmldoc->_private = 0;
1298 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1299 hr = S_FALSE;
1302 TRACE("ret (%d)\n", hr);
1304 return hr;
1308 static HRESULT WINAPI domdoc_get_readyState(
1309 IXMLDOMDocument2 *iface,
1310 long* value )
1312 FIXME("\n");
1313 return E_NOTIMPL;
1317 static HRESULT WINAPI domdoc_get_parseError(
1318 IXMLDOMDocument2 *iface,
1319 IXMLDOMParseError** errorObj )
1321 BSTR error_string = NULL;
1322 static const WCHAR err[] = {'e','r','r','o','r',0};
1323 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1325 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1327 if(This->error)
1328 error_string = SysAllocString(err);
1330 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1331 if(!*errorObj) return E_OUTOFMEMORY;
1332 return S_OK;
1336 static HRESULT WINAPI domdoc_get_url(
1337 IXMLDOMDocument2 *iface,
1338 BSTR* urlString )
1340 FIXME("\n");
1341 return E_NOTIMPL;
1345 static HRESULT WINAPI domdoc_get_async(
1346 IXMLDOMDocument2 *iface,
1347 VARIANT_BOOL* isAsync )
1349 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1351 TRACE("%p <- %d\n", isAsync, This->async);
1352 *isAsync = This->async;
1353 return S_OK;
1357 static HRESULT WINAPI domdoc_put_async(
1358 IXMLDOMDocument2 *iface,
1359 VARIANT_BOOL isAsync )
1361 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1363 TRACE("%d\n", isAsync);
1364 This->async = isAsync;
1365 return S_OK;
1369 static HRESULT WINAPI domdoc_abort(
1370 IXMLDOMDocument2 *iface )
1372 FIXME("\n");
1373 return E_NOTIMPL;
1377 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1379 UINT len, blen = SysStringLen( bstr );
1380 LPSTR str;
1382 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1383 str = HeapAlloc( GetProcessHeap(), 0, len );
1384 if ( !str )
1385 return FALSE;
1386 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1387 *plen = len;
1388 *pstr = str;
1389 return TRUE;
1392 static HRESULT WINAPI domdoc_loadXML(
1393 IXMLDOMDocument2 *iface,
1394 BSTR bstrXML,
1395 VARIANT_BOOL* isSuccessful )
1397 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1398 xmlDocPtr xmldoc = NULL;
1399 char *str;
1400 int len;
1401 HRESULT hr = S_FALSE;
1403 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1405 assert ( This->node );
1407 attach_xmlnode( This->node, NULL );
1409 if ( isSuccessful )
1411 *isSuccessful = VARIANT_FALSE;
1413 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1415 xmldoc = doparse( str, len );
1416 HeapFree( GetProcessHeap(), 0, str );
1417 if ( !xmldoc )
1418 This->error = E_FAIL;
1419 else
1421 hr = This->error = S_OK;
1422 *isSuccessful = VARIANT_TRUE;
1426 if(!xmldoc)
1427 xmldoc = xmlNewDoc(NULL);
1429 xmldoc->_private = 0;
1430 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1432 return hr;
1436 static HRESULT WINAPI domdoc_save(
1437 IXMLDOMDocument2 *iface,
1438 VARIANT destination )
1440 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1441 HANDLE handle;
1442 xmlChar *mem, *p;
1443 int size;
1444 HRESULT ret = S_OK;
1445 DWORD written;
1447 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1448 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1450 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1452 FIXME("Unhandled vt %d\n", V_VT(&destination));
1453 return S_FALSE;
1456 if(V_VT(&destination) == VT_UNKNOWN)
1458 IUnknown *pUnk = V_UNKNOWN(&destination);
1459 IXMLDOMDocument *pDocument;
1461 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1462 if(ret == S_OK)
1464 BSTR bXML;
1465 VARIANT_BOOL bSuccessful;
1467 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1468 if(ret == S_OK)
1470 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1472 SysFreeString(bXML);
1475 IXMLDOMDocument_Release(pDocument);
1478 TRACE("ret %d", ret);
1480 return ret;
1483 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1484 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1485 if( handle == INVALID_HANDLE_VALUE )
1487 WARN("failed to create file\n");
1488 return S_FALSE;
1491 xmlDocDumpMemory(get_doc(This), &mem, &size);
1494 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1495 * MSXML adds XML declaration only for processing instruction nodes.
1496 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1498 p = mem;
1499 if(size > 2 && p[0] == '<' && p[1] == '?') {
1500 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1501 p++;
1502 p += 2;
1503 while(p < mem+size && isspace(*p))
1504 p++;
1505 size -= p-mem;
1508 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1510 WARN("write error\n");
1511 ret = S_FALSE;
1514 xmlFree(mem);
1515 CloseHandle(handle);
1516 return ret;
1519 static HRESULT WINAPI domdoc_get_validateOnParse(
1520 IXMLDOMDocument2 *iface,
1521 VARIANT_BOOL* isValidating )
1523 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1525 TRACE("%p <- %d\n", isValidating, This->validating);
1526 *isValidating = This->validating;
1527 return S_OK;
1531 static HRESULT WINAPI domdoc_put_validateOnParse(
1532 IXMLDOMDocument2 *iface,
1533 VARIANT_BOOL isValidating )
1535 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1537 TRACE("%d\n", isValidating);
1538 This->validating = isValidating;
1539 return S_OK;
1543 static HRESULT WINAPI domdoc_get_resolveExternals(
1544 IXMLDOMDocument2 *iface,
1545 VARIANT_BOOL* isResolving )
1547 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1549 TRACE("%p <- %d\n", isResolving, This->resolving);
1550 *isResolving = This->resolving;
1551 return S_OK;
1555 static HRESULT WINAPI domdoc_put_resolveExternals(
1556 IXMLDOMDocument2 *iface,
1557 VARIANT_BOOL isResolving )
1559 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1561 TRACE("%d\n", isResolving);
1562 This->resolving = isResolving;
1563 return S_OK;
1567 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1568 IXMLDOMDocument2 *iface,
1569 VARIANT_BOOL* isPreserving )
1571 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1573 TRACE("%p <- %d\n", isPreserving, This->preserving);
1574 *isPreserving = This->preserving;
1575 return S_OK;
1579 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1580 IXMLDOMDocument2 *iface,
1581 VARIANT_BOOL isPreserving )
1583 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1585 TRACE("%d\n", isPreserving);
1586 This->preserving = isPreserving;
1587 return S_OK;
1591 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1592 IXMLDOMDocument2 *iface,
1593 VARIANT readyStateChangeSink )
1595 FIXME("\n");
1596 return E_NOTIMPL;
1600 static HRESULT WINAPI domdoc_put_onDataAvailable(
1601 IXMLDOMDocument2 *iface,
1602 VARIANT onDataAvailableSink )
1604 FIXME("\n");
1605 return E_NOTIMPL;
1608 static HRESULT WINAPI domdoc_put_onTransformNode(
1609 IXMLDOMDocument2 *iface,
1610 VARIANT onTransformNodeSink )
1612 FIXME("\n");
1613 return E_NOTIMPL;
1616 static HRESULT WINAPI domdoc_get_namespaces(
1617 IXMLDOMDocument2* iface,
1618 IXMLDOMSchemaCollection** schemaCollection )
1620 FIXME("\n");
1621 return E_NOTIMPL;
1624 static HRESULT WINAPI domdoc_get_schemas(
1625 IXMLDOMDocument2* iface,
1626 VARIANT* var1 )
1628 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1629 HRESULT hr = S_FALSE;
1630 IXMLDOMSchemaCollection *cur_schema = This->schema;
1632 TRACE("(%p)->(%p)\n", This, var1);
1634 VariantInit(var1); /* Test shows we don't call VariantClear here */
1635 V_VT(var1) = VT_NULL;
1637 if(cur_schema)
1639 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1640 if(SUCCEEDED(hr))
1641 V_VT(var1) = VT_DISPATCH;
1643 return hr;
1646 static HRESULT WINAPI domdoc_putref_schemas(
1647 IXMLDOMDocument2* iface,
1648 VARIANT var1)
1650 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1651 HRESULT hr = E_FAIL;
1652 IXMLDOMSchemaCollection *new_schema = NULL;
1654 FIXME("(%p): semi-stub\n", This);
1655 switch(V_VT(&var1))
1657 case VT_UNKNOWN:
1658 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1659 break;
1661 case VT_DISPATCH:
1662 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1663 break;
1665 case VT_NULL:
1666 case VT_EMPTY:
1667 hr = S_OK;
1668 break;
1670 default:
1671 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1674 if(SUCCEEDED(hr))
1676 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1677 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1680 return hr;
1683 static HRESULT WINAPI domdoc_validate(
1684 IXMLDOMDocument2* iface,
1685 IXMLDOMParseError** err)
1687 FIXME("\n");
1688 return E_NOTIMPL;
1691 static HRESULT WINAPI domdoc_setProperty(
1692 IXMLDOMDocument2* iface,
1693 BSTR p,
1694 VARIANT var)
1696 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1698 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1700 VARIANT varStr;
1701 HRESULT hr;
1702 BSTR bstr;
1704 V_VT(&varStr) = VT_EMPTY;
1705 if (V_VT(&var) != VT_BSTR)
1707 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1708 return hr;
1709 bstr = V_BSTR(&varStr);
1711 else
1712 bstr = V_BSTR(&var);
1714 hr = S_OK;
1715 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1716 This->bUseXPath = TRUE;
1717 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1718 This->bUseXPath = FALSE;
1719 else
1720 hr = E_FAIL;
1722 VariantClear(&varStr);
1723 return hr;
1726 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1727 return E_FAIL;
1730 static HRESULT WINAPI domdoc_getProperty(
1731 IXMLDOMDocument2* iface,
1732 BSTR p,
1733 VARIANT* var)
1735 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1737 if (var == NULL)
1738 return E_INVALIDARG;
1739 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1741 V_VT(var) = VT_BSTR;
1742 if (This->bUseXPath)
1743 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1744 else
1745 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1746 return S_OK;
1749 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1750 return E_FAIL;
1753 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1755 domdoc_QueryInterface,
1756 domdoc_AddRef,
1757 domdoc_Release,
1758 domdoc_GetTypeInfoCount,
1759 domdoc_GetTypeInfo,
1760 domdoc_GetIDsOfNames,
1761 domdoc_Invoke,
1762 domdoc_get_nodeName,
1763 domdoc_get_nodeValue,
1764 domdoc_put_nodeValue,
1765 domdoc_get_nodeType,
1766 domdoc_get_parentNode,
1767 domdoc_get_childNodes,
1768 domdoc_get_firstChild,
1769 domdoc_get_lastChild,
1770 domdoc_get_previousSibling,
1771 domdoc_get_nextSibling,
1772 domdoc_get_attributes,
1773 domdoc_insertBefore,
1774 domdoc_replaceChild,
1775 domdoc_removeChild,
1776 domdoc_appendChild,
1777 domdoc_hasChildNodes,
1778 domdoc_get_ownerDocument,
1779 domdoc_cloneNode,
1780 domdoc_get_nodeTypeString,
1781 domdoc_get_text,
1782 domdoc_put_text,
1783 domdoc_get_specified,
1784 domdoc_get_definition,
1785 domdoc_get_nodeTypedValue,
1786 domdoc_put_nodeTypedValue,
1787 domdoc_get_dataType,
1788 domdoc_put_dataType,
1789 domdoc_get_xml,
1790 domdoc_transformNode,
1791 domdoc_selectNodes,
1792 domdoc_selectSingleNode,
1793 domdoc_get_parsed,
1794 domdoc_get_namespaceURI,
1795 domdoc_get_prefix,
1796 domdoc_get_baseName,
1797 domdoc_transformNodeToObject,
1798 domdoc_get_doctype,
1799 domdoc_get_implementation,
1800 domdoc_get_documentElement,
1801 domdoc_put_documentElement,
1802 domdoc_createElement,
1803 domdoc_createDocumentFragment,
1804 domdoc_createTextNode,
1805 domdoc_createComment,
1806 domdoc_createCDATASection,
1807 domdoc_createProcessingInstruction,
1808 domdoc_createAttribute,
1809 domdoc_createEntityReference,
1810 domdoc_getElementsByTagName,
1811 domdoc_createNode,
1812 domdoc_nodeFromID,
1813 domdoc_load,
1814 domdoc_get_readyState,
1815 domdoc_get_parseError,
1816 domdoc_get_url,
1817 domdoc_get_async,
1818 domdoc_put_async,
1819 domdoc_abort,
1820 domdoc_loadXML,
1821 domdoc_save,
1822 domdoc_get_validateOnParse,
1823 domdoc_put_validateOnParse,
1824 domdoc_get_resolveExternals,
1825 domdoc_put_resolveExternals,
1826 domdoc_get_preserveWhiteSpace,
1827 domdoc_put_preserveWhiteSpace,
1828 domdoc_put_onReadyStateChange,
1829 domdoc_put_onDataAvailable,
1830 domdoc_put_onTransformNode,
1831 domdoc_get_namespaces,
1832 domdoc_get_schemas,
1833 domdoc_putref_schemas,
1834 domdoc_validate,
1835 domdoc_setProperty,
1836 domdoc_getProperty
1839 /* xmldoc implementation of IObjectWithSite */
1840 static HRESULT WINAPI
1841 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
1843 domdoc *This = impl_from_IObjectWithSite(iface);
1844 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
1847 static ULONG WINAPI
1848 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
1850 domdoc *This = impl_from_IObjectWithSite(iface);
1851 return IXMLDocument_AddRef((IXMLDocument *)This);
1854 static ULONG WINAPI
1855 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
1857 domdoc *This = impl_from_IObjectWithSite(iface);
1858 return IXMLDocument_Release((IXMLDocument *)This);
1861 static HRESULT WINAPI
1862 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
1864 domdoc *This = impl_from_IObjectWithSite(iface);
1866 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
1868 if ( !This->site )
1869 return E_FAIL;
1871 return IUnknown_QueryInterface( This->site, iid, ppvSite );
1874 static HRESULT WINAPI
1875 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
1877 domdoc *This = impl_from_IObjectWithSite(iface);
1879 TRACE("%p %p\n", iface, punk);
1881 if(!punk)
1883 if(This->site)
1885 IUnknown_Release( This->site );
1886 This->site = NULL;
1889 return S_OK;
1892 if ( punk )
1893 IUnknown_AddRef( punk );
1895 if(This->site)
1896 IUnknown_Release( This->site );
1898 This->site = punk;
1900 return S_OK;
1903 static const IObjectWithSiteVtbl domdocObjectSite =
1905 xmldoc_ObjectWithSite_QueryInterface,
1906 xmldoc_ObjectWithSite_AddRef,
1907 xmldoc_ObjectWithSite_Release,
1908 xmldoc_SetSite,
1909 xmldoc_GetSite,
1912 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1914 domdoc *This = impl_from_IObjectSafety(iface);
1915 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
1918 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
1920 domdoc *This = impl_from_IObjectSafety(iface);
1921 return IXMLDocument_AddRef((IXMLDocument *)This);
1924 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
1926 domdoc *This = impl_from_IObjectSafety(iface);
1927 return IXMLDocument_Release((IXMLDocument *)This);
1930 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
1932 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1933 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1935 domdoc *This = impl_from_IObjectSafety(iface);
1937 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
1939 if(!pdwSupportedOptions || !pdwEnabledOptions)
1940 return E_POINTER;
1942 *pdwSupportedOptions = SUPPORTED_OPTIONS;
1943 *pdwEnabledOptions = This->safeopt;
1945 return S_OK;
1948 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1949 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1951 domdoc *This = impl_from_IObjectSafety(iface);
1953 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
1955 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
1956 return E_FAIL;
1958 This->safeopt = dwEnabledOptions & dwEnabledOptions;
1959 return S_OK;
1962 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
1963 xmldoc_Safety_QueryInterface,
1964 xmldoc_Safety_AddRef,
1965 xmldoc_Safety_Release,
1966 xmldoc_Safety_GetInterfaceSafetyOptions,
1967 xmldoc_Safety_SetInterfaceSafetyOptions
1970 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
1972 domdoc *doc;
1973 HRESULT hr;
1975 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1976 if( !doc )
1977 return E_OUTOFMEMORY;
1979 doc->lpVtbl = &domdoc_vtbl;
1980 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
1981 doc->lpvtblIObjectWithSite = &domdocObjectSite;
1982 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
1983 doc->ref = 1;
1984 doc->async = 0;
1985 doc->validating = 0;
1986 doc->resolving = 0;
1987 doc->preserving = 0;
1988 doc->bUseXPath = FALSE;
1989 doc->error = S_OK;
1990 doc->schema = NULL;
1991 doc->stream = NULL;
1992 doc->site = NULL;
1993 doc->safeopt = 0;
1994 doc->bsc = NULL;
1996 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1997 if(!doc->node_unk)
1999 HeapFree(GetProcessHeap(), 0, doc);
2000 return E_FAIL;
2003 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2004 if(FAILED(hr))
2006 IUnknown_Release(doc->node_unk);
2007 HeapFree( GetProcessHeap(), 0, doc );
2008 return E_FAIL;
2010 /* The ref on doc->node is actually looped back into this object, so release it */
2011 IXMLDOMNode_Release(doc->node);
2013 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2015 TRACE("returning iface %p\n", *document);
2016 return S_OK;
2019 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2021 xmlDocPtr xmldoc;
2022 HRESULT hr;
2024 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2026 xmldoc = xmlNewDoc(NULL);
2027 if(!xmldoc)
2028 return E_OUTOFMEMORY;
2030 xmldoc->_private = 0;
2032 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2033 if(FAILED(hr))
2034 xmlFreeDoc(xmldoc);
2036 return hr;
2039 IUnknown* create_domdoc( xmlNodePtr document )
2041 HRESULT hr;
2042 LPVOID pObj = NULL;
2044 TRACE("(%p)\n", document);
2046 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2047 if (FAILED(hr))
2048 return NULL;
2050 return (IUnknown*)pObj;
2053 #else
2055 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2057 MESSAGE("This program tried to use a DOMDocument object, but\n"
2058 "libxml2 support was not present at compile time.\n");
2059 return E_NOTIMPL;
2062 #endif