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,
752 static HRESULT WINAPI domdoc_createComment(
753 IXMLDOMDocument2 *iface,
755 IXMLDOMComment** comment )
762 static HRESULT WINAPI domdoc_createCDATASection(
763 IXMLDOMDocument2 *iface,
765 IXMLDOMCDATASection** cdata )
772 static HRESULT WINAPI domdoc_createProcessingInstruction(
773 IXMLDOMDocument2 *iface,
776 IXMLDOMProcessingInstruction** pi )
778 #ifdef HAVE_XMLNEWDOCPI
780 domdoc *This = impl_from_IXMLDOMDocument2( iface );
781 xmlChar *xml_target, *xml_content;
783 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
785 xml_target = xmlChar_from_wchar((WCHAR*)target);
786 xml_content = xmlChar_from_wchar((WCHAR*)data);
788 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
789 TRACE("created xmlptr %p\n", xmlnode);
790 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
792 HeapFree(GetProcessHeap(), 0, xml_content);
793 HeapFree(GetProcessHeap(), 0, xml_target);
797 FIXME("Libxml 2.6.15 or greater required.\n");
803 static HRESULT WINAPI domdoc_createAttribute(
804 IXMLDOMDocument2 *iface,
806 IXMLDOMAttribute** attribute )
813 static HRESULT WINAPI domdoc_createEntityReference(
814 IXMLDOMDocument2 *iface,
816 IXMLDOMEntityReference** entityRef )
823 static HRESULT WINAPI domdoc_getElementsByTagName(
824 IXMLDOMDocument2 *iface,
826 IXMLDOMNodeList** resultList )
828 domdoc *This = impl_from_IXMLDOMDocument2( iface );
831 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
833 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
834 szPattern[0] = szPattern[1] = '/';
835 lstrcpyW(szPattern + 2, tagName);
837 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
838 HeapFree(GetProcessHeap(), 0, szPattern);
843 static DOMNodeType get_node_type(VARIANT Type)
845 if(V_VT(&Type) == VT_I4)
848 FIXME("Unsupported variant type %x\n", V_VT(&Type));
852 static HRESULT WINAPI domdoc_createNode(
853 IXMLDOMDocument2 *iface,
859 domdoc *This = impl_from_IXMLDOMDocument2( iface );
860 DOMNodeType node_type;
861 xmlNodePtr xmlnode = NULL;
864 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
866 node_type = get_node_type(Type);
867 TRACE("node_type %d\n", node_type);
869 xml_name = xmlChar_from_wchar((WCHAR*)name);
874 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
875 *node = create_node(xmlnode);
876 TRACE("created %p\n", xmlnode);
880 FIXME("unhandled node type %d\n", node_type);
884 HeapFree(GetProcessHeap(), 0, xml_name);
892 static HRESULT WINAPI domdoc_nodeFromID(
893 IXMLDOMDocument2 *iface,
901 static xmlDocPtr doparse( char *ptr, int len )
903 #ifdef HAVE_XMLREADMEMORY
905 * use xmlReadMemory if possible so we can suppress
906 * writing errors to stderr
908 return xmlReadMemory( ptr, len, NULL, NULL,
909 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
911 return xmlParseMemory( ptr, len );
915 static xmlDocPtr doread( LPWSTR filename )
917 xmlDocPtr xmldoc = NULL;
920 IStream *stream, *memstream;
921 WCHAR url[INTERNET_MAX_URL_LENGTH];
925 TRACE("%s\n", debugstr_w( filename ));
927 if(!PathIsURLW(filename))
929 WCHAR fullpath[MAX_PATH];
930 DWORD needed = sizeof(url)/sizeof(WCHAR);
932 if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
934 WARN("can't find path\n");
938 if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
940 ERR("can't create url from path\n");
946 hr = CreateBindCtx(0, &pbc);
949 hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&domdoc_bsc.lpVtbl, NULL, 0);
953 hr = CreateURLMoniker(NULL, filename, &moniker);
956 hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
957 IMoniker_Release(moniker);
960 IBindCtx_Release(pbc);
965 hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
968 IStream_Release(stream);
974 IStream_Read(stream, buf, sizeof(buf), &read);
975 hr = IStream_Write(memstream, buf, read, &written);
976 } while(SUCCEEDED(hr) && written != 0 && read != 0);
981 hr = GetHGlobalFromStream(memstream, &hglobal);
984 DWORD len = GlobalSize(hglobal);
985 char *ptr = GlobalLock(hglobal);
987 xmldoc = doparse( ptr, len );
988 GlobalUnlock(hglobal);
991 IStream_Release(memstream);
992 IStream_Release(stream);
996 static HRESULT WINAPI domdoc_load(
997 IXMLDOMDocument2 *iface,
999 VARIANT_BOOL* isSuccessful )
1001 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1002 LPWSTR filename = NULL;
1003 xmlDocPtr xmldoc = NULL;
1004 HRESULT hr = S_FALSE;
1006 TRACE("type %d\n", V_VT(&xmlSource) );
1008 *isSuccessful = VARIANT_FALSE;
1010 assert( This->node );
1012 attach_xmlnode(This->node, NULL);
1014 switch( V_VT(&xmlSource) )
1017 filename = V_BSTR(&xmlSource);
1022 xmldoc = doread( filename );
1025 This->error = E_FAIL;
1028 hr = This->error = S_OK;
1029 *isSuccessful = VARIANT_TRUE;
1034 xmldoc = xmlNewDoc(NULL);
1036 xmldoc->_private = 0;
1037 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1043 static HRESULT WINAPI domdoc_get_readyState(
1044 IXMLDOMDocument2 *iface,
1052 static HRESULT WINAPI domdoc_get_parseError(
1053 IXMLDOMDocument2 *iface,
1054 IXMLDOMParseError** errorObj )
1056 BSTR error_string = NULL;
1057 static const WCHAR err[] = {'e','r','r','o','r',0};
1058 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1060 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1063 error_string = SysAllocString(err);
1065 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1066 if(!*errorObj) return E_OUTOFMEMORY;
1071 static HRESULT WINAPI domdoc_get_url(
1072 IXMLDOMDocument2 *iface,
1080 static HRESULT WINAPI domdoc_get_async(
1081 IXMLDOMDocument2 *iface,
1082 VARIANT_BOOL* isAsync )
1084 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1086 TRACE("%p <- %d\n", isAsync, This->async);
1087 *isAsync = This->async;
1092 static HRESULT WINAPI domdoc_put_async(
1093 IXMLDOMDocument2 *iface,
1094 VARIANT_BOOL isAsync )
1096 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1098 TRACE("%d\n", isAsync);
1099 This->async = isAsync;
1104 static HRESULT WINAPI domdoc_abort(
1105 IXMLDOMDocument2 *iface )
1112 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1114 UINT len, blen = SysStringLen( bstr );
1117 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1118 str = HeapAlloc( GetProcessHeap(), 0, len );
1121 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1127 static HRESULT WINAPI domdoc_loadXML(
1128 IXMLDOMDocument2 *iface,
1130 VARIANT_BOOL* isSuccessful )
1132 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1133 xmlDocPtr xmldoc = NULL;
1136 HRESULT hr = S_FALSE;
1138 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1140 assert ( This->node );
1142 attach_xmlnode( This->node, NULL );
1146 *isSuccessful = VARIANT_FALSE;
1148 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1150 xmldoc = doparse( str, len );
1151 HeapFree( GetProcessHeap(), 0, str );
1153 This->error = E_FAIL;
1156 hr = This->error = S_OK;
1157 *isSuccessful = VARIANT_TRUE;
1162 xmldoc = xmlNewDoc(NULL);
1164 xmldoc->_private = 0;
1165 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1171 static HRESULT WINAPI domdoc_save(
1172 IXMLDOMDocument2 *iface,
1173 VARIANT destination )
1175 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1182 TRACE("(%p)->(var(vt %x, %s))\n", This, V_VT(&destination),
1183 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1185 if(V_VT(&destination) != VT_BSTR)
1187 FIXME("Unhandled vt %x\n", V_VT(&destination));
1191 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1192 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1193 if( handle == INVALID_HANDLE_VALUE )
1195 WARN("failed to create file\n");
1199 xmlDocDumpMemory(get_doc(This), &mem, &size);
1200 if(!WriteFile(handle, mem, (DWORD)size, &written, NULL) || written != (DWORD)size)
1202 WARN("write error\n");
1207 CloseHandle(handle);
1211 static HRESULT WINAPI domdoc_get_validateOnParse(
1212 IXMLDOMDocument2 *iface,
1213 VARIANT_BOOL* isValidating )
1215 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1217 TRACE("%p <- %d\n", isValidating, This->validating);
1218 *isValidating = This->validating;
1223 static HRESULT WINAPI domdoc_put_validateOnParse(
1224 IXMLDOMDocument2 *iface,
1225 VARIANT_BOOL isValidating )
1227 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1229 TRACE("%d\n", isValidating);
1230 This->validating = isValidating;
1235 static HRESULT WINAPI domdoc_get_resolveExternals(
1236 IXMLDOMDocument2 *iface,
1237 VARIANT_BOOL* isResolving )
1239 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1241 TRACE("%p <- %d\n", isResolving, This->resolving);
1242 *isResolving = This->resolving;
1247 static HRESULT WINAPI domdoc_put_resolveExternals(
1248 IXMLDOMDocument2 *iface,
1249 VARIANT_BOOL isResolving )
1251 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1253 TRACE("%d\n", isResolving);
1254 This->resolving = isResolving;
1259 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1260 IXMLDOMDocument2 *iface,
1261 VARIANT_BOOL* isPreserving )
1263 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1265 TRACE("%p <- %d\n", isPreserving, This->preserving);
1266 *isPreserving = This->preserving;
1271 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1272 IXMLDOMDocument2 *iface,
1273 VARIANT_BOOL isPreserving )
1275 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1277 TRACE("%d\n", isPreserving);
1278 This->preserving = isPreserving;
1283 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1284 IXMLDOMDocument2 *iface,
1285 VARIANT readyStateChangeSink )
1292 static HRESULT WINAPI domdoc_put_onDataAvailable(
1293 IXMLDOMDocument2 *iface,
1294 VARIANT onDataAvailableSink )
1300 static HRESULT WINAPI domdoc_put_onTransformNode(
1301 IXMLDOMDocument2 *iface,
1302 VARIANT onTransformNodeSink )
1308 static HRESULT WINAPI domdoc_get_namespaces(
1309 IXMLDOMDocument2* iface,
1310 IXMLDOMSchemaCollection** schemaCollection )
1316 static HRESULT WINAPI domdoc_get_schemas(
1317 IXMLDOMDocument2* iface,
1320 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1321 HRESULT hr = S_FALSE;
1322 IXMLDOMSchemaCollection *cur_schema = This->schema;
1324 TRACE("(%p)->(%p)\n", This, var1);
1326 VariantInit(var1); /* Test shows we don't call VariantClear here */
1327 V_VT(var1) = VT_NULL;
1331 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1333 V_VT(var1) = VT_DISPATCH;
1338 static HRESULT WINAPI domdoc_putref_schemas(
1339 IXMLDOMDocument2* iface,
1342 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1343 HRESULT hr = E_FAIL;
1344 IXMLDOMSchemaCollection *new_schema = NULL;
1346 FIXME("(%p): semi-stub\n", This);
1350 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1354 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1363 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1368 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1369 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1375 static HRESULT WINAPI domdoc_validate(
1376 IXMLDOMDocument2* iface,
1377 IXMLDOMParseError** err)
1383 static HRESULT WINAPI domdoc_setProperty(
1384 IXMLDOMDocument2* iface,
1388 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1390 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1396 V_VT(&varStr) = VT_EMPTY;
1397 if (V_VT(&var) != VT_BSTR)
1399 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1401 bstr = V_BSTR(&varStr);
1404 bstr = V_BSTR(&var);
1407 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1408 This->bUseXPath = TRUE;
1409 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1410 This->bUseXPath = FALSE;
1414 VariantClear(&varStr);
1418 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1422 static HRESULT WINAPI domdoc_getProperty(
1423 IXMLDOMDocument2* iface,
1427 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1430 return E_INVALIDARG;
1431 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1433 V_VT(var) = VT_BSTR;
1434 if (This->bUseXPath)
1435 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1437 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1441 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1445 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1447 domdoc_QueryInterface,
1450 domdoc_GetTypeInfoCount,
1452 domdoc_GetIDsOfNames,
1454 domdoc_get_nodeName,
1455 domdoc_get_nodeValue,
1456 domdoc_put_nodeValue,
1457 domdoc_get_nodeType,
1458 domdoc_get_parentNode,
1459 domdoc_get_childNodes,
1460 domdoc_get_firstChild,
1461 domdoc_get_lastChild,
1462 domdoc_get_previousSibling,
1463 domdoc_get_nextSibling,
1464 domdoc_get_attributes,
1465 domdoc_insertBefore,
1466 domdoc_replaceChild,
1469 domdoc_hasChildNodes,
1470 domdoc_get_ownerDocument,
1472 domdoc_get_nodeTypeString,
1475 domdoc_get_specified,
1476 domdoc_get_definition,
1477 domdoc_get_nodeTypedValue,
1478 domdoc_put_nodeTypedValue,
1479 domdoc_get_dataType,
1480 domdoc_put_dataType,
1482 domdoc_transformNode,
1484 domdoc_selectSingleNode,
1486 domdoc_get_namespaceURI,
1488 domdoc_get_baseName,
1489 domdoc_transformNodeToObject,
1491 domdoc_get_implementation,
1492 domdoc_get_documentElement,
1493 domdoc_documentElement,
1494 domdoc_createElement,
1495 domdoc_createDocumentFragment,
1496 domdoc_createTextNode,
1497 domdoc_createComment,
1498 domdoc_createCDATASection,
1499 domdoc_createProcessingInstruction,
1500 domdoc_createAttribute,
1501 domdoc_createEntityReference,
1502 domdoc_getElementsByTagName,
1506 domdoc_get_readyState,
1507 domdoc_get_parseError,
1514 domdoc_get_validateOnParse,
1515 domdoc_put_validateOnParse,
1516 domdoc_get_resolveExternals,
1517 domdoc_put_resolveExternals,
1518 domdoc_get_preserveWhiteSpace,
1519 domdoc_put_preserveWhiteSpace,
1520 domdoc_put_onReadyStateChange,
1521 domdoc_put_onDataAvailable,
1522 domdoc_put_onTransformNode,
1523 domdoc_get_namespaces,
1525 domdoc_putref_schemas,
1531 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1537 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
1539 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
1541 return E_OUTOFMEMORY;
1543 doc->lpVtbl = &domdoc_vtbl;
1546 doc->validating = 0;
1548 doc->preserving = 0;
1549 doc->bUseXPath = FALSE;
1553 xmldoc = xmlNewDoc(NULL);
1556 HeapFree(GetProcessHeap(), 0, doc);
1557 return E_OUTOFMEMORY;
1560 xmldoc->_private = 0;
1562 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
1566 HeapFree(GetProcessHeap(), 0, doc);
1570 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
1573 IUnknown_Release(doc->node_unk);
1574 HeapFree( GetProcessHeap(), 0, doc );
1577 /* The ref on doc->node is actually looped back into this object, so release it */
1578 IXMLDOMNode_Release(doc->node);
1580 *ppObj = &doc->lpVtbl;
1582 TRACE("returning iface %p\n", *ppObj);
1588 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
1590 MESSAGE("This program tried to use a DOMDocument object, but\n"
1591 "libxml2 support was not present at compile time.\n");