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
38 #include "wine/debug.h"
40 #include "msxml_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
46 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};
47 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
48 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
51 const struct IBindStatusCallbackVtbl *lpVtbl;
54 static HRESULT WINAPI bsc_QueryInterface(
55 IBindStatusCallback *iface,
59 if (IsEqualGUID(riid, &IID_IUnknown) ||
60 IsEqualGUID(riid, &IID_IBindStatusCallback))
62 IBindStatusCallback_AddRef( iface );
67 FIXME("interface %s not implemented\n", debugstr_guid(riid));
71 static ULONG WINAPI bsc_AddRef(
72 IBindStatusCallback *iface )
77 static ULONG WINAPI bsc_Release(
78 IBindStatusCallback *iface )
83 static HRESULT WINAPI bsc_OnStartBinding(
84 IBindStatusCallback* iface,
91 static HRESULT WINAPI bsc_GetPriority(
92 IBindStatusCallback* iface,
98 static HRESULT WINAPI bsc_OnLowResource(
99 IBindStatusCallback* iface,
105 static HRESULT WINAPI bsc_OnProgress(
106 IBindStatusCallback* iface,
110 LPCWSTR szStatusText)
115 static HRESULT WINAPI bsc_OnStopBinding(
116 IBindStatusCallback* iface,
123 static HRESULT WINAPI bsc_GetBindInfo(
124 IBindStatusCallback* iface,
128 *grfBINDF = BINDF_RESYNCHRONIZE;
133 static HRESULT WINAPI bsc_OnDataAvailable(
134 IBindStatusCallback* iface,
137 FORMATETC* pformatetc,
143 static HRESULT WINAPI bsc_OnObjectAvailable(
144 IBindStatusCallback* iface,
151 static const struct IBindStatusCallbackVtbl bsc_vtbl =
163 bsc_OnObjectAvailable
166 static bsc domdoc_bsc = { &bsc_vtbl };
168 typedef struct _domdoc
170 const struct IXMLDOMDocument2Vtbl *lpVtbl;
173 VARIANT_BOOL validating;
174 VARIANT_BOOL resolving;
175 VARIANT_BOOL preserving;
179 IXMLDOMSchemaCollection *schema;
183 LONG xmldoc_add_ref(xmlDocPtr doc)
185 LONG ref = InterlockedIncrement((LONG*)&doc->_private);
190 LONG xmldoc_release(xmlDocPtr doc)
192 LONG ref = InterlockedDecrement((LONG*)&doc->_private);
196 TRACE("freeing docptr %p\n", doc);
203 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
205 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
208 static inline xmlDocPtr get_doc( domdoc *This )
210 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
213 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
215 domdoc *This = impl_from_IXMLDOMDocument2( iface );
217 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
219 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
220 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
221 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
225 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
226 IsEqualGUID( riid, &IID_IDispatch ) )
228 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
232 FIXME("interface %s not implemented\n", debugstr_guid(riid));
233 return E_NOINTERFACE;
236 IXMLDOMDocument_AddRef( iface );
242 static ULONG WINAPI domdoc_AddRef(
243 IXMLDOMDocument2 *iface )
245 domdoc *This = impl_from_IXMLDOMDocument2( iface );
246 TRACE("%p\n", This );
247 return InterlockedIncrement( &This->ref );
251 static ULONG WINAPI domdoc_Release(
252 IXMLDOMDocument2 *iface )
254 domdoc *This = impl_from_IXMLDOMDocument2( iface );
257 TRACE("%p\n", This );
259 ref = InterlockedDecrement( &This->ref );
262 IUnknown_Release( This->node_unk );
263 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
264 HeapFree( GetProcessHeap(), 0, This );
270 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
276 static HRESULT WINAPI domdoc_GetTypeInfo(
277 IXMLDOMDocument2 *iface,
278 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
284 static HRESULT WINAPI domdoc_GetIDsOfNames(
285 IXMLDOMDocument2 *iface,
297 static HRESULT WINAPI domdoc_Invoke(
298 IXMLDOMDocument2 *iface,
303 DISPPARAMS* pDispParams,
305 EXCEPINFO* pExcepInfo,
313 static HRESULT WINAPI domdoc_get_nodeName(
314 IXMLDOMDocument2 *iface,
317 domdoc *This = impl_from_IXMLDOMDocument2( iface );
318 return IXMLDOMNode_get_nodeName( This->node, name );
322 static HRESULT WINAPI domdoc_get_nodeValue(
323 IXMLDOMDocument2 *iface,
326 domdoc *This = impl_from_IXMLDOMDocument2( iface );
327 return IXMLDOMNode_get_nodeValue( This->node, value );
331 static HRESULT WINAPI domdoc_put_nodeValue(
332 IXMLDOMDocument2 *iface,
335 domdoc *This = impl_from_IXMLDOMDocument2( iface );
336 return IXMLDOMNode_put_nodeValue( This->node, value );
340 static HRESULT WINAPI domdoc_get_nodeType(
341 IXMLDOMDocument2 *iface,
344 domdoc *This = impl_from_IXMLDOMDocument2( iface );
345 return IXMLDOMNode_get_nodeType( This->node, type );
349 static HRESULT WINAPI domdoc_get_parentNode(
350 IXMLDOMDocument2 *iface,
351 IXMLDOMNode** parent )
353 domdoc *This = impl_from_IXMLDOMDocument2( iface );
354 return IXMLDOMNode_get_parentNode( This->node, parent );
358 static HRESULT WINAPI domdoc_get_childNodes(
359 IXMLDOMDocument2 *iface,
360 IXMLDOMNodeList** childList )
362 domdoc *This = impl_from_IXMLDOMDocument2( iface );
363 return IXMLDOMNode_get_childNodes( This->node, childList );
367 static HRESULT WINAPI domdoc_get_firstChild(
368 IXMLDOMDocument2 *iface,
369 IXMLDOMNode** firstChild )
371 domdoc *This = impl_from_IXMLDOMDocument2( iface );
372 return IXMLDOMNode_get_firstChild( This->node, firstChild );
376 static HRESULT WINAPI domdoc_get_lastChild(
377 IXMLDOMDocument2 *iface,
378 IXMLDOMNode** lastChild )
380 domdoc *This = impl_from_IXMLDOMDocument2( iface );
381 return IXMLDOMNode_get_lastChild( This->node, lastChild );
385 static HRESULT WINAPI domdoc_get_previousSibling(
386 IXMLDOMDocument2 *iface,
387 IXMLDOMNode** previousSibling )
389 domdoc *This = impl_from_IXMLDOMDocument2( iface );
390 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
394 static HRESULT WINAPI domdoc_get_nextSibling(
395 IXMLDOMDocument2 *iface,
396 IXMLDOMNode** nextSibling )
398 domdoc *This = impl_from_IXMLDOMDocument2( iface );
399 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
403 static HRESULT WINAPI domdoc_get_attributes(
404 IXMLDOMDocument2 *iface,
405 IXMLDOMNamedNodeMap** attributeMap )
407 domdoc *This = impl_from_IXMLDOMDocument2( iface );
408 return IXMLDOMNode_get_attributes( This->node, attributeMap );
412 static HRESULT WINAPI domdoc_insertBefore(
413 IXMLDOMDocument2 *iface,
414 IXMLDOMNode* newChild,
416 IXMLDOMNode** outNewChild )
418 domdoc *This = impl_from_IXMLDOMDocument2( iface );
419 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
423 static HRESULT WINAPI domdoc_replaceChild(
424 IXMLDOMDocument2 *iface,
425 IXMLDOMNode* newChild,
426 IXMLDOMNode* oldChild,
427 IXMLDOMNode** outOldChild)
429 domdoc *This = impl_from_IXMLDOMDocument2( iface );
430 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
434 static HRESULT WINAPI domdoc_removeChild(
435 IXMLDOMDocument2 *iface,
436 IXMLDOMNode* childNode,
437 IXMLDOMNode** oldChild)
439 domdoc *This = impl_from_IXMLDOMDocument2( iface );
440 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
444 static HRESULT WINAPI domdoc_appendChild(
445 IXMLDOMDocument2 *iface,
446 IXMLDOMNode* newChild,
447 IXMLDOMNode** outNewChild)
449 domdoc *This = impl_from_IXMLDOMDocument2( iface );
450 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
454 static HRESULT WINAPI domdoc_hasChildNodes(
455 IXMLDOMDocument2 *iface,
456 VARIANT_BOOL* hasChild)
458 domdoc *This = impl_from_IXMLDOMDocument2( iface );
459 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
463 static HRESULT WINAPI domdoc_get_ownerDocument(
464 IXMLDOMDocument2 *iface,
465 IXMLDOMDocument** DOMDocument)
467 domdoc *This = impl_from_IXMLDOMDocument2( iface );
468 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
472 static HRESULT WINAPI domdoc_cloneNode(
473 IXMLDOMDocument2 *iface,
475 IXMLDOMNode** cloneRoot)
477 domdoc *This = impl_from_IXMLDOMDocument2( iface );
478 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
482 static HRESULT WINAPI domdoc_get_nodeTypeString(
483 IXMLDOMDocument2 *iface,
486 domdoc *This = impl_from_IXMLDOMDocument2( iface );
487 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
491 static HRESULT WINAPI domdoc_get_text(
492 IXMLDOMDocument2 *iface,
495 domdoc *This = impl_from_IXMLDOMDocument2( iface );
496 return IXMLDOMNode_get_text( This->node, text );
500 static HRESULT WINAPI domdoc_put_text(
501 IXMLDOMDocument2 *iface,
504 domdoc *This = impl_from_IXMLDOMDocument2( iface );
505 return IXMLDOMNode_put_text( This->node, text );
509 static HRESULT WINAPI domdoc_get_specified(
510 IXMLDOMDocument2 *iface,
511 VARIANT_BOOL* isSpecified )
513 domdoc *This = impl_from_IXMLDOMDocument2( iface );
514 return IXMLDOMNode_get_specified( This->node, isSpecified );
518 static HRESULT WINAPI domdoc_get_definition(
519 IXMLDOMDocument2 *iface,
520 IXMLDOMNode** definitionNode )
522 domdoc *This = impl_from_IXMLDOMDocument2( iface );
523 return IXMLDOMNode_get_definition( This->node, definitionNode );
527 static HRESULT WINAPI domdoc_get_nodeTypedValue(
528 IXMLDOMDocument2 *iface,
529 VARIANT* typedValue )
531 domdoc *This = impl_from_IXMLDOMDocument2( iface );
532 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
535 static HRESULT WINAPI domdoc_put_nodeTypedValue(
536 IXMLDOMDocument2 *iface,
539 domdoc *This = impl_from_IXMLDOMDocument2( iface );
540 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
544 static HRESULT WINAPI domdoc_get_dataType(
545 IXMLDOMDocument2 *iface,
546 VARIANT* dataTypeName )
548 domdoc *This = impl_from_IXMLDOMDocument2( iface );
549 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
553 static HRESULT WINAPI domdoc_put_dataType(
554 IXMLDOMDocument2 *iface,
557 domdoc *This = impl_from_IXMLDOMDocument2( iface );
558 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
562 static HRESULT WINAPI domdoc_get_xml(
563 IXMLDOMDocument2 *iface,
566 domdoc *This = impl_from_IXMLDOMDocument2( iface );
567 return IXMLDOMNode_get_xml( This->node, xmlString );
571 static HRESULT WINAPI domdoc_transformNode(
572 IXMLDOMDocument2 *iface,
573 IXMLDOMNode* styleSheet,
576 domdoc *This = impl_from_IXMLDOMDocument2( iface );
577 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
581 static HRESULT WINAPI domdoc_selectNodes(
582 IXMLDOMDocument2 *iface,
584 IXMLDOMNodeList** resultList )
586 domdoc *This = impl_from_IXMLDOMDocument2( iface );
587 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
591 static HRESULT WINAPI domdoc_selectSingleNode(
592 IXMLDOMDocument2 *iface,
594 IXMLDOMNode** resultNode )
596 domdoc *This = impl_from_IXMLDOMDocument2( iface );
597 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
601 static HRESULT WINAPI domdoc_get_parsed(
602 IXMLDOMDocument2 *iface,
603 VARIANT_BOOL* isParsed )
605 domdoc *This = impl_from_IXMLDOMDocument2( iface );
606 return IXMLDOMNode_get_parsed( This->node, isParsed );
610 static HRESULT WINAPI domdoc_get_namespaceURI(
611 IXMLDOMDocument2 *iface,
614 domdoc *This = impl_from_IXMLDOMDocument2( iface );
615 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
619 static HRESULT WINAPI domdoc_get_prefix(
620 IXMLDOMDocument2 *iface,
623 domdoc *This = impl_from_IXMLDOMDocument2( iface );
624 return IXMLDOMNode_get_prefix( This->node, prefixString );
628 static HRESULT WINAPI domdoc_get_baseName(
629 IXMLDOMDocument2 *iface,
632 domdoc *This = impl_from_IXMLDOMDocument2( iface );
633 return IXMLDOMNode_get_baseName( This->node, nameString );
637 static HRESULT WINAPI domdoc_transformNodeToObject(
638 IXMLDOMDocument2 *iface,
639 IXMLDOMNode* stylesheet,
640 VARIANT outputObject)
642 domdoc *This = impl_from_IXMLDOMDocument2( iface );
643 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
647 static HRESULT WINAPI domdoc_get_doctype(
648 IXMLDOMDocument2 *iface,
649 IXMLDOMDocumentType** documentType )
656 static HRESULT WINAPI domdoc_get_implementation(
657 IXMLDOMDocument2 *iface,
658 IXMLDOMImplementation** impl )
664 static HRESULT WINAPI domdoc_get_documentElement(
665 IXMLDOMDocument2 *iface,
666 IXMLDOMElement** DOMElement )
668 domdoc *This = impl_from_IXMLDOMDocument2( iface );
669 xmlDocPtr xmldoc = NULL;
670 xmlNodePtr root = NULL;
671 IXMLDOMNode *element_node;
674 TRACE("%p %p\n", This, This->node);
681 xmldoc = get_doc( This );
683 root = xmlDocGetRootElement( xmldoc );
687 element_node = create_node( root );
688 if(!element_node) return S_FALSE;
690 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
691 IXMLDOMNode_Release(element_node);
697 static HRESULT WINAPI domdoc_documentElement(
698 IXMLDOMDocument2 *iface,
699 IXMLDOMElement* DOMElement )
706 static HRESULT WINAPI domdoc_createElement(
707 IXMLDOMDocument2 *iface,
709 IXMLDOMElement** element )
712 domdoc *This = impl_from_IXMLDOMDocument2( iface );
717 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
719 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
720 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
722 TRACE("created xmlptr %p\n", xmlnode);
723 elem_unk = create_element(xmlnode, NULL);
724 HeapFree(GetProcessHeap(), 0, xml_name);
726 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
727 IUnknown_Release(elem_unk);
728 TRACE("returning %p\n", *element);
733 static HRESULT WINAPI domdoc_createDocumentFragment(
734 IXMLDOMDocument2 *iface,
735 IXMLDOMDocumentFragment** docFrag )
742 static HRESULT WINAPI domdoc_createTextNode(
743 IXMLDOMDocument2 *iface,
747 domdoc *This = impl_from_IXMLDOMDocument2( iface );
749 xmlChar *xml_content;
751 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
758 xml_content = xmlChar_from_wchar((WCHAR*)data);
759 xmlnode = xmlNewText(xml_content);
760 HeapFree(GetProcessHeap(), 0, xml_content);
765 xmlnode->doc = get_doc( This );
767 *text = (IXMLDOMText*)create_text(xmlnode);
773 static HRESULT WINAPI domdoc_createComment(
774 IXMLDOMDocument2 *iface,
776 IXMLDOMComment** comment )
783 static HRESULT WINAPI domdoc_createCDATASection(
784 IXMLDOMDocument2 *iface,
786 IXMLDOMCDATASection** cdata )
793 static HRESULT WINAPI domdoc_createProcessingInstruction(
794 IXMLDOMDocument2 *iface,
797 IXMLDOMProcessingInstruction** pi )
799 #ifdef HAVE_XMLNEWDOCPI
801 domdoc *This = impl_from_IXMLDOMDocument2( iface );
802 xmlChar *xml_target, *xml_content;
804 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
806 xml_target = xmlChar_from_wchar((WCHAR*)target);
807 xml_content = xmlChar_from_wchar((WCHAR*)data);
809 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
810 TRACE("created xmlptr %p\n", xmlnode);
811 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
813 HeapFree(GetProcessHeap(), 0, xml_content);
814 HeapFree(GetProcessHeap(), 0, xml_target);
818 FIXME("Libxml 2.6.15 or greater required.\n");
824 static HRESULT WINAPI domdoc_createAttribute(
825 IXMLDOMDocument2 *iface,
827 IXMLDOMAttribute** attribute )
834 static HRESULT WINAPI domdoc_createEntityReference(
835 IXMLDOMDocument2 *iface,
837 IXMLDOMEntityReference** entityRef )
844 static HRESULT WINAPI domdoc_getElementsByTagName(
845 IXMLDOMDocument2 *iface,
847 IXMLDOMNodeList** resultList )
849 domdoc *This = impl_from_IXMLDOMDocument2( iface );
852 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
854 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
855 szPattern[0] = szPattern[1] = '/';
856 lstrcpyW(szPattern + 2, tagName);
858 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
859 HeapFree(GetProcessHeap(), 0, szPattern);
864 static DOMNodeType get_node_type(VARIANT Type)
866 if(V_VT(&Type) == VT_I4)
869 FIXME("Unsupported variant type %x\n", V_VT(&Type));
873 static HRESULT WINAPI domdoc_createNode(
874 IXMLDOMDocument2 *iface,
880 domdoc *This = impl_from_IXMLDOMDocument2( iface );
881 DOMNodeType node_type;
882 xmlNodePtr xmlnode = NULL;
885 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
887 node_type = get_node_type(Type);
888 TRACE("node_type %d\n", node_type);
890 xml_name = xmlChar_from_wchar((WCHAR*)name);
895 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
896 *node = create_node(xmlnode);
897 TRACE("created %p\n", xmlnode);
901 FIXME("unhandled node type %d\n", node_type);
905 HeapFree(GetProcessHeap(), 0, xml_name);
913 static HRESULT WINAPI domdoc_nodeFromID(
914 IXMLDOMDocument2 *iface,
922 static xmlDocPtr doparse( char *ptr, int len )
924 #ifdef HAVE_XMLREADMEMORY
926 * use xmlReadMemory if possible so we can suppress
927 * writing errors to stderr
929 return xmlReadMemory( ptr, len, NULL, NULL,
930 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
932 return xmlParseMemory( ptr, len );
936 static xmlDocPtr doread( LPWSTR filename )
938 xmlDocPtr xmldoc = NULL;
941 IStream *stream, *memstream;
942 WCHAR url[INTERNET_MAX_URL_LENGTH];
946 TRACE("%s\n", debugstr_w( filename ));
948 if(!PathIsURLW(filename))
950 WCHAR fullpath[MAX_PATH];
951 DWORD needed = sizeof(url)/sizeof(WCHAR);
953 if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
955 WARN("can't find path\n");
959 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
961 ERR("can't create url from path\n");
967 hr = CreateBindCtx(0, &pbc);
970 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
974 hr = CreateURLMoniker(NULL, filename, &moniker);
977 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
978 IMoniker_Release(moniker);
981 IBindCtx_Release(pbc);
986 hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
989 IStream_Release(stream);
995 IStream_Read(stream, buf, sizeof(buf), &read);
996 hr = IStream_Write(memstream, buf, read, &written);
997 } while(SUCCEEDED(hr) && written != 0 && read != 0);
1002 hr = GetHGlobalFromStream(memstream, &hglobal);
1005 DWORD len = GlobalSize(hglobal);
1006 char *ptr = GlobalLock(hglobal);
1008 xmldoc = doparse( ptr, len );
1009 GlobalUnlock(hglobal);
1012 IStream_Release(memstream);
1013 IStream_Release(stream);
1017 static HRESULT WINAPI domdoc_load(
1018 IXMLDOMDocument2 *iface,
1020 VARIANT_BOOL* isSuccessful )
1022 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1023 LPWSTR filename = NULL;
1024 xmlDocPtr xmldoc = NULL;
1025 HRESULT hr = S_FALSE;
1027 TRACE("type %d\n", V_VT(&xmlSource) );
1029 *isSuccessful = VARIANT_FALSE;
1031 assert( This->node );
1033 attach_xmlnode(This->node, NULL);
1035 switch( V_VT(&xmlSource) )
1038 filename = V_BSTR(&xmlSource);
1043 xmldoc = doread( filename );
1046 This->error = E_FAIL;
1049 hr = This->error = S_OK;
1050 *isSuccessful = VARIANT_TRUE;
1055 xmldoc = xmlNewDoc(NULL);
1057 xmldoc->_private = 0;
1058 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1064 static HRESULT WINAPI domdoc_get_readyState(
1065 IXMLDOMDocument2 *iface,
1073 static HRESULT WINAPI domdoc_get_parseError(
1074 IXMLDOMDocument2 *iface,
1075 IXMLDOMParseError** errorObj )
1077 BSTR error_string = NULL;
1078 static const WCHAR err[] = {'e','r','r','o','r',0};
1079 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1081 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1084 error_string = SysAllocString(err);
1086 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1087 if(!*errorObj) return E_OUTOFMEMORY;
1092 static HRESULT WINAPI domdoc_get_url(
1093 IXMLDOMDocument2 *iface,
1101 static HRESULT WINAPI domdoc_get_async(
1102 IXMLDOMDocument2 *iface,
1103 VARIANT_BOOL* isAsync )
1105 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1107 TRACE("%p <- %d\n", isAsync, This->async);
1108 *isAsync = This->async;
1113 static HRESULT WINAPI domdoc_put_async(
1114 IXMLDOMDocument2 *iface,
1115 VARIANT_BOOL isAsync )
1117 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1119 TRACE("%d\n", isAsync);
1120 This->async = isAsync;
1125 static HRESULT WINAPI domdoc_abort(
1126 IXMLDOMDocument2 *iface )
1133 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1135 UINT len, blen = SysStringLen( bstr );
1138 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1139 str = HeapAlloc( GetProcessHeap(), 0, len );
1142 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1148 static HRESULT WINAPI domdoc_loadXML(
1149 IXMLDOMDocument2 *iface,
1151 VARIANT_BOOL* isSuccessful )
1153 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1154 xmlDocPtr xmldoc = NULL;
1157 HRESULT hr = S_FALSE;
1159 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1161 assert ( This->node );
1163 attach_xmlnode( This->node, NULL );
1167 *isSuccessful = VARIANT_FALSE;
1169 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1171 xmldoc = doparse( str, len );
1172 HeapFree( GetProcessHeap(), 0, str );
1174 This->error = E_FAIL;
1177 hr = This->error = S_OK;
1178 *isSuccessful = VARIANT_TRUE;
1183 xmldoc = xmlNewDoc(NULL);
1185 xmldoc->_private = 0;
1186 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1192 static HRESULT WINAPI domdoc_save(
1193 IXMLDOMDocument2 *iface,
1194 VARIANT destination )
1196 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1203 TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1204 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1206 if(V_VT(&destination) != VT_BSTR)
1208 FIXME("Unhandled vt %x\n", V_VT(&destination));
1212 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1213 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1214 if( handle == INVALID_HANDLE_VALUE )
1216 WARN("failed to create file\n");
1220 xmlDocDumpMemory(get_doc(This), &mem, &size);
1221 if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1223 WARN("write error\n");
1228 CloseHandle(handle);
1232 static HRESULT WINAPI domdoc_get_validateOnParse(
1233 IXMLDOMDocument2 *iface,
1234 VARIANT_BOOL* isValidating )
1236 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1238 TRACE("%p <- %d\n", isValidating, This->validating);
1239 *isValidating = This->validating;
1244 static HRESULT WINAPI domdoc_put_validateOnParse(
1245 IXMLDOMDocument2 *iface,
1246 VARIANT_BOOL isValidating )
1248 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1250 TRACE("%d\n", isValidating);
1251 This->validating = isValidating;
1256 static HRESULT WINAPI domdoc_get_resolveExternals(
1257 IXMLDOMDocument2 *iface,
1258 VARIANT_BOOL* isResolving )
1260 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1262 TRACE("%p <- %d\n", isResolving, This->resolving);
1263 *isResolving = This->resolving;
1268 static HRESULT WINAPI domdoc_put_resolveExternals(
1269 IXMLDOMDocument2 *iface,
1270 VARIANT_BOOL isResolving )
1272 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1274 TRACE("%d\n", isResolving);
1275 This->resolving = isResolving;
1280 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1281 IXMLDOMDocument2 *iface,
1282 VARIANT_BOOL* isPreserving )
1284 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1286 TRACE("%p <- %d\n", isPreserving, This->preserving);
1287 *isPreserving = This->preserving;
1292 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1293 IXMLDOMDocument2 *iface,
1294 VARIANT_BOOL isPreserving )
1296 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1298 TRACE("%d\n", isPreserving);
1299 This->preserving = isPreserving;
1304 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1305 IXMLDOMDocument2 *iface,
1306 VARIANT readyStateChangeSink )
1313 static HRESULT WINAPI domdoc_put_onDataAvailable(
1314 IXMLDOMDocument2 *iface,
1315 VARIANT onDataAvailableSink )
1321 static HRESULT WINAPI domdoc_put_onTransformNode(
1322 IXMLDOMDocument2 *iface,
1323 VARIANT onTransformNodeSink )
1329 static HRESULT WINAPI domdoc_get_namespaces(
1330 IXMLDOMDocument2* iface,
1331 IXMLDOMSchemaCollection** schemaCollection )
1337 static HRESULT WINAPI domdoc_get_schemas(
1338 IXMLDOMDocument2* iface,
1341 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1342 HRESULT hr = S_FALSE;
1343 IXMLDOMSchemaCollection *cur_schema = This->schema;
1345 TRACE("(%p)->(%p)\n", This, var1);
1347 VariantInit(var1); /* Test shows we don't call VariantClear here */
1348 V_VT(var1) = VT_NULL;
1352 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1354 V_VT(var1) = VT_DISPATCH;
1359 static HRESULT WINAPI domdoc_putref_schemas(
1360 IXMLDOMDocument2* iface,
1363 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1364 HRESULT hr = E_FAIL;
1365 IXMLDOMSchemaCollection *new_schema = NULL;
1367 FIXME("(%p): semi-stub\n", This);
1371 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1375 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1384 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1389 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1390 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1396 static HRESULT WINAPI domdoc_validate(
1397 IXMLDOMDocument2* iface,
1398 IXMLDOMParseError** err)
1404 static HRESULT WINAPI domdoc_setProperty(
1405 IXMLDOMDocument2* iface,
1409 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1411 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1417 V_VT(&varStr) = VT_EMPTY;
1418 if (V_VT(&var) != VT_BSTR)
1420 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1422 bstr = V_BSTR(&varStr);
1425 bstr = V_BSTR(&var);
1428 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1429 This->bUseXPath = TRUE;
1430 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1431 This->bUseXPath = FALSE;
1435 VariantClear(&varStr);
1439 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1443 static HRESULT WINAPI domdoc_getProperty(
1444 IXMLDOMDocument2* iface,
1448 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1451 return E_INVALIDARG;
1452 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1454 V_VT(var) = VT_BSTR;
1455 if (This->bUseXPath)
1456 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1458 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1462 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1466 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1468 domdoc_QueryInterface,
1471 domdoc_GetTypeInfoCount,
1473 domdoc_GetIDsOfNames,
1475 domdoc_get_nodeName,
1476 domdoc_get_nodeValue,
1477 domdoc_put_nodeValue,
1478 domdoc_get_nodeType,
1479 domdoc_get_parentNode,
1480 domdoc_get_childNodes,
1481 domdoc_get_firstChild,
1482 domdoc_get_lastChild,
1483 domdoc_get_previousSibling,
1484 domdoc_get_nextSibling,
1485 domdoc_get_attributes,
1486 domdoc_insertBefore,
1487 domdoc_replaceChild,
1490 domdoc_hasChildNodes,
1491 domdoc_get_ownerDocument,
1493 domdoc_get_nodeTypeString,
1496 domdoc_get_specified,
1497 domdoc_get_definition,
1498 domdoc_get_nodeTypedValue,
1499 domdoc_put_nodeTypedValue,
1500 domdoc_get_dataType,
1501 domdoc_put_dataType,
1503 domdoc_transformNode,
1505 domdoc_selectSingleNode,
1507 domdoc_get_namespaceURI,
1509 domdoc_get_baseName,
1510 domdoc_transformNodeToObject,
1512 domdoc_get_implementation,
1513 domdoc_get_documentElement,
1514 domdoc_documentElement,
1515 domdoc_createElement,
1516 domdoc_createDocumentFragment,
1517 domdoc_createTextNode,
1518 domdoc_createComment,
1519 domdoc_createCDATASection,
1520 domdoc_createProcessingInstruction,
1521 domdoc_createAttribute,
1522 domdoc_createEntityReference,
1523 domdoc_getElementsByTagName,
1527 domdoc_get_readyState,
1528 domdoc_get_parseError,
1535 domdoc_get_validateOnParse,
1536 domdoc_put_validateOnParse,
1537 domdoc_get_resolveExternals,
1538 domdoc_put_resolveExternals,
1539 domdoc_get_preserveWhiteSpace,
1540 domdoc_put_preserveWhiteSpace,
1541 domdoc_put_onReadyStateChange,
1542 domdoc_put_onDataAvailable,
1543 domdoc_put_onTransformNode,
1544 domdoc_get_namespaces,
1546 domdoc_putref_schemas,
1552 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1558 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1560 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1562 return E_OUTOFMEMORY;
1564 doc->lpVtbl = &domdoc_vtbl;
1567 doc->validating = 0;
1569 doc->preserving = 0;
1570 doc->bUseXPath = FALSE;
1574 xmldoc = xmlNewDoc(NULL);
1577 HeapFree(GetProcessHeap(), 0, doc);
1578 return E_OUTOFMEMORY;
1581 xmldoc->_private = 0;
1583 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1587 HeapFree(GetProcessHeap(), 0, doc);
1591 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1594 IUnknown_Release(doc->node_unk);
1595 HeapFree( GetProcessHeap(), 0, doc );
1598 /* The ref on doc->node is actually looped back into this object, so release it */
1599 IXMLDOMNode_Release(doc->node);
1601 *ppObj = &doc->lpVtbl;
1603 TRACE("returning iface %p\n", *ppObj);
1609 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1611 MESSAGE("This program tried to use a DOMDocument object, but\n"
1612 "libxml2 support was not present at compile time.\n");