diff --git a/reactos/dll/win32/msxml3/attribute.c b/reactos/dll/win32/msxml3/attribute.c index edd33d019ae..6bd7a5809d1 100644 --- a/reactos/dll/win32/msxml3/attribute.c +++ b/reactos/dll/win32/msxml3/attribute.c @@ -606,7 +606,7 @@ static HRESULT WINAPI domattr_put_value( TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); - return node_put_value(&This->node, &value); + return node_put_value_escaped(&This->node, &value); } static const struct IXMLDOMAttributeVtbl domattr_vtbl = diff --git a/reactos/dll/win32/msxml3/cdata.c b/reactos/dll/win32/msxml3/cdata.c index b7d8e3884e7..cbf72cb58a2 100644 --- a/reactos/dll/win32/msxml3/cdata.c +++ b/reactos/dll/win32/msxml3/cdata.c @@ -293,10 +293,9 @@ static HRESULT WINAPI domcdata_insertBefore( IXMLDOMNode** outOldNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - - FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode); - - return node_insert_before(&This->node, newNode, &refChild, outOldNode); + TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode); + if (outOldNode) *outOldNode = NULL; + return E_FAIL; } static HRESULT WINAPI domcdata_replaceChild( @@ -306,10 +305,9 @@ static HRESULT WINAPI domcdata_replaceChild( IXMLDOMNode** outOldNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - - FIXME("(%p)->(%p %p %p) needs tests\n", This, newNode, oldNode, outOldNode); - - return node_replace_child(&This->node, newNode, oldNode, outOldNode); + TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode); + if (outOldNode) *outOldNode = NULL; + return E_FAIL; } static HRESULT WINAPI domcdata_removeChild( @@ -318,7 +316,8 @@ static HRESULT WINAPI domcdata_removeChild( { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); TRACE("(%p)->(%p %p)\n", This, child, oldChild); - return node_remove_child(&This->node, child, oldChild); + if (oldChild) *oldChild = NULL; + return E_FAIL; } static HRESULT WINAPI domcdata_appendChild( @@ -327,7 +326,8 @@ static HRESULT WINAPI domcdata_appendChild( { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); TRACE("(%p)->(%p %p)\n", This, child, outChild); - return node_append_child(&This->node, child, outChild); + if (outChild) *outChild = NULL; + return E_FAIL; } static HRESULT WINAPI domcdata_hasChildNodes( diff --git a/reactos/dll/win32/msxml3/dispex.c b/reactos/dll/win32/msxml3/dispex.c index 4384f9836e7..9eb5ae33e5b 100644 --- a/reactos/dll/win32/msxml3/dispex.c +++ b/reactos/dll/win32/msxml3/dispex.c @@ -601,6 +601,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc hres = IUnknown_QueryInterface(This->outer, get_riid_from_tid(data->funcs[n].tid), (void**)&unk); if(FAILED(hres)) { ERR("Could not get iface: %08x\n", hres); + ITypeInfo_Release(ti); return E_FAIL; } diff --git a/reactos/dll/win32/msxml3/domdoc.c b/reactos/dll/win32/msxml3/domdoc.c index 15075e3f58b..9828482f5c0 100644 --- a/reactos/dll/win32/msxml3/domdoc.c +++ b/reactos/dll/win32/msxml3/domdoc.c @@ -135,9 +135,6 @@ struct domdoc bsc_t *bsc; HRESULT error; - /* IPersistStream */ - IStream *stream; - /* IObjectWithSite*/ IUnknown *site; @@ -559,19 +556,28 @@ void xmldoc_init(xmlDocPtr doc, MSXML_VERSION version) priv_from_xmlDocPtr(doc)->properties = create_properties(version); } -LONG xmldoc_add_ref(xmlDocPtr doc) +LONG xmldoc_add_refs(xmlDocPtr doc, LONG refs) { - LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs); + LONG ref = InterlockedExchangeAdd(&priv_from_xmlDocPtr(doc)->refs, refs) + refs; TRACE("(%p)->(%d)\n", doc, ref); return ref; } -LONG xmldoc_release(xmlDocPtr doc) +LONG xmldoc_add_ref(xmlDocPtr doc) +{ + return xmldoc_add_refs(doc, 1); +} + +LONG xmldoc_release_refs(xmlDocPtr doc, LONG refs) { xmldoc_priv *priv = priv_from_xmlDocPtr(doc); - LONG ref = InterlockedDecrement(&priv->refs); + LONG ref = InterlockedExchangeAdd(&priv->refs, -refs) - refs; TRACE("(%p)->(%d)\n", doc, ref); - if(ref == 0) + + if (ref < 0) + WARN("negative refcount, expect troubles\n"); + + if (ref == 0) { orphan_entry *orphan, *orphan2; TRACE("freeing docptr %p\n", doc); @@ -590,6 +596,11 @@ LONG xmldoc_release(xmlDocPtr doc) return ref; } +LONG xmldoc_release(xmlDocPtr doc) +{ + return xmldoc_release_refs(doc, 1); +} + HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node) { xmldoc_priv *priv = priv_from_xmlDocPtr(doc); @@ -624,7 +635,7 @@ HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node) static inline xmlDocPtr get_doc( domdoc *This ) { - return (xmlDocPtr)This->node.node; + return This->node.node->doc; } static HRESULT attach_xmldoc(domdoc *This, xmlDocPtr xml ) @@ -721,46 +732,42 @@ static HRESULT WINAPI PersistStreamInit_IsDirty( return S_FALSE; } -static HRESULT WINAPI PersistStreamInit_Load( - IPersistStreamInit *iface, LPSTREAM pStm) +static HRESULT domdoc_load_from_stream(domdoc *doc, ISequentialStream *stream) { - domdoc *This = impl_from_IPersistStreamInit(iface); - HRESULT hr; - HGLOBAL hglobal; DWORD read, written, len; - BYTE buf[4096]; - char *ptr; xmlDocPtr xmldoc = NULL; + IStream *hstream; + HGLOBAL hglobal; + BYTE buf[4096]; + HRESULT hr; + char *ptr; - TRACE("(%p)->(%p)\n", This, pStm); - - if (!pStm) - return E_INVALIDARG; - - hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream); + hstream = NULL; + hr = CreateStreamOnHGlobal(NULL, TRUE, &hstream); if (FAILED(hr)) return hr; do { - IStream_Read(pStm, buf, sizeof(buf), &read); - hr = IStream_Write(This->stream, buf, read, &written); + ISequentialStream_Read(stream, buf, sizeof(buf), &read); + hr = IStream_Write(hstream, buf, read, &written); } while(SUCCEEDED(hr) && written != 0 && read != 0); if (FAILED(hr)) { - ERR("Failed to copy stream\n"); + ERR("failed to copy stream 0x%08x\n", hr); + IStream_Release(hstream); return hr; } - hr = GetHGlobalFromStream(This->stream, &hglobal); + hr = GetHGlobalFromStream(hstream, &hglobal); if (FAILED(hr)) return hr; len = GlobalSize(hglobal); ptr = GlobalLock(hglobal); - if (len != 0) - xmldoc = doparse(This, ptr, len, XML_CHAR_ENCODING_NONE); + if (len) + xmldoc = doparse(doc, ptr, len, XML_CHAR_ENCODING_NONE); GlobalUnlock(hglobal); if (!xmldoc) @@ -771,7 +778,19 @@ static HRESULT WINAPI PersistStreamInit_Load( xmldoc->_private = create_priv(); - return attach_xmldoc(This, xmldoc); + return attach_xmldoc(doc, xmldoc); +} + +static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, IStream *stream) +{ + domdoc *This = impl_from_IPersistStreamInit(iface); + + TRACE("(%p)->(%p)\n", This, stream); + + if (!stream) + return E_INVALIDARG; + + return domdoc_load_from_stream(This, (ISequentialStream*)stream); } static HRESULT WINAPI PersistStreamInit_Save( @@ -801,7 +820,7 @@ static HRESULT WINAPI PersistStreamInit_GetSizeMax( IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize) { domdoc *This = impl_from_IPersistStreamInit(iface); - TRACE("(%p)->(%p): stub!\n", This, pcbSize); + TRACE("(%p)->(%p)\n", This, pcbSize); return E_NOTIMPL; } @@ -914,8 +933,6 @@ static ULONG WINAPI domdoc_Release( IXMLDOMDocument3 *iface ) if (This->site) IUnknown_Release( This->site ); destroy_xmlnode(&This->node); - if (This->stream) - IStream_Release(This->stream); for (eid = 0; eid < EVENTID_LAST; eid++) if (This->events[eid]) IDispatch_Release(This->events[eid]); @@ -1115,12 +1132,26 @@ static HRESULT WINAPI domdoc_insertBefore( IXMLDOMNode** outNewChild ) { domdoc *This = impl_from_IXMLDOMDocument3( iface ); + DOMNodeType type; + HRESULT hr; TRACE("(%p)->(%p %s %p)\n", This, newChild, debugstr_variant(&refChild), outNewChild); - return node_insert_before(&This->node, newChild, &refChild, outNewChild); -} + hr = IXMLDOMNode_get_nodeType(newChild, &type); + if (hr != S_OK) return hr; + TRACE("new node type %d\n", type); + switch (type) + { + case NODE_ATTRIBUTE: + case NODE_DOCUMENT: + case NODE_CDATA_SECTION: + if (outNewChild) *outNewChild = NULL; + return E_FAIL; + default: + return node_insert_before(&This->node, newChild, &refChild, outNewChild); + } +} static HRESULT WINAPI domdoc_replaceChild( IXMLDOMDocument3 *iface, @@ -1510,7 +1541,9 @@ static HRESULT WINAPI domdoc_put_documentElement( domdoc *This = impl_from_IXMLDOMDocument3( iface ); IXMLDOMNode *elementNode; xmlNodePtr oldRoot; + xmlDocPtr old_doc; xmlnode *xmlNode; + int refcount = 0; HRESULT hr; TRACE("(%p)->(%p)\n", This, DOMElement); @@ -1526,7 +1559,14 @@ static HRESULT WINAPI domdoc_put_documentElement( if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK) WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node); + old_doc = xmlNode->node->doc; + if (old_doc != get_doc(This)) + refcount = xmlnode_get_inst_cnt(xmlNode); + + /* old root is still orphaned by its document, update refcount from new root */ + if (refcount) xmldoc_add_refs(get_doc(This), refcount); oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node); + if (refcount) xmldoc_release_refs(old_doc, refcount); IXMLDOMNode_Release( elementNode ); if(oldRoot) @@ -2029,8 +2069,6 @@ static HRESULT WINAPI domdoc_load( domdoc *This = impl_from_IXMLDOMDocument3( iface ); LPWSTR filename = NULL; HRESULT hr = S_FALSE; - IXMLDOMDocument3 *pNewDoc = NULL; - IStream *pStream = NULL; xmlDocPtr xmldoc; TRACE("(%p)->(%s)\n", This, debugstr_variant(&source)); @@ -2096,13 +2134,18 @@ static HRESULT WINAPI domdoc_load( } break; case VT_UNKNOWN: + { + ISequentialStream *stream = NULL; + IXMLDOMDocument3 *newdoc = NULL; + if (!V_UNKNOWN(&source)) return E_INVALIDARG; - hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_IXMLDOMDocument3, (void**)&pNewDoc); + + hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_IXMLDOMDocument3, (void**)&newdoc); if(hr == S_OK) { - if(pNewDoc) + if(newdoc) { - domdoc *newDoc = impl_from_IXMLDOMDocument3( pNewDoc ); + domdoc *newDoc = impl_from_IXMLDOMDocument3( newdoc ); xmldoc = xmlCopyDoc(get_doc(newDoc), 1); xmldoc->_private = create_priv(); @@ -2114,40 +2157,25 @@ static HRESULT WINAPI domdoc_load( return hr; } } - hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_IStream, (void**)&pStream); - if(hr == S_OK) - { - IPersistStream *pDocStream; - hr = IXMLDOMDocument3_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream); - if(hr == S_OK) - { - hr = IPersistStream_Load(pDocStream, pStream); - IStream_Release(pStream); - if(hr == S_OK) - { - *isSuccessful = VARIANT_TRUE; - TRACE("Using IStream to load Document\n"); - return S_OK; - } - else - { - ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr); - } - } - else - { - ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr); - } - } - else + hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_IStream, (void**)&stream); + if (FAILED(hr)) + hr = IUnknown_QueryInterface(V_UNKNOWN(&source), &IID_ISequentialStream, (void**)&stream); + + if (hr == S_OK) { - /* ISequentialStream */ - FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&source)->lpVtbl); + hr = domdoc_load_from_stream(This, stream); + if (hr == S_OK) + *isSuccessful = VARIANT_TRUE; + ISequentialStream_Release(stream); + return hr; } + + FIXME("unsupported IUnknown type (0x%08x) (%p)\n", hr, V_UNKNOWN(&source)->lpVtbl); break; - default: - FIXME("VT type not supported (%d)\n", V_VT(&source)); + } + default: + FIXME("VT type not supported (%d)\n", V_VT(&source)); } if ( filename ) @@ -3251,12 +3279,43 @@ static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoi return S_OK; } -static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink, - DWORD *pdwCookie) +static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *unk_sink, + DWORD *cookie) { ConnectionPoint *This = impl_from_IConnectionPoint(iface); - FIXME("(%p)->(%p %p): stub\n", This, pUnkSink, pdwCookie); - return E_NOTIMPL; + IUnknown *sink; + HRESULT hr; + DWORD i; + + TRACE("(%p)->(%p %p)\n", This, unk_sink, cookie); + + hr = IUnknown_QueryInterface(unk_sink, This->iid, (void**)&sink); + if(FAILED(hr) && !IsEqualGUID(&IID_IPropertyNotifySink, This->iid)) + hr = IUnknown_QueryInterface(unk_sink, &IID_IDispatch, (void**)&sink); + if(FAILED(hr)) + return CONNECT_E_CANNOTCONNECT; + + if(This->sinks) + { + for (i = 0; i < This->sinks_size; i++) + if (!This->sinks[i].unk) + break; + + if (i == This->sinks_size) + This->sinks = heap_realloc(This->sinks,(++This->sinks_size)*sizeof(*This->sinks)); + } + else + { + This->sinks = heap_alloc(sizeof(*This->sinks)); + This->sinks_size = 1; + i = 0; + } + + This->sinks[i].unk = sink; + if (cookie) + *cookie = i+1; + + return S_OK; } static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD cookie) @@ -3466,7 +3525,6 @@ HRESULT get_domdoc_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document) doc->resolving = 0; doc->properties = properties_from_xmlDocPtr(xmldoc); doc->error = S_OK; - doc->stream = NULL; doc->site = NULL; doc->safeopt = 0; doc->bsc = NULL; diff --git a/reactos/dll/win32/msxml3/element.c b/reactos/dll/win32/msxml3/element.c index cfc4165f66d..1cdc0f84b8b 100644 --- a/reactos/dll/win32/msxml3/element.c +++ b/reactos/dll/win32/msxml3/element.c @@ -304,13 +304,29 @@ static HRESULT WINAPI domelem_get_attributes( static HRESULT WINAPI domelem_insertBefore( IXMLDOMElement *iface, IXMLDOMNode* newNode, VARIANT refChild, - IXMLDOMNode** outOldNode) + IXMLDOMNode** old_node) { domelem *This = impl_from_IXMLDOMElement( iface ); + DOMNodeType type; + HRESULT hr; - TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode); + TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), old_node); - return node_insert_before(&This->node, newNode, &refChild, outOldNode); + hr = IXMLDOMNode_get_nodeType(newNode, &type); + if (hr != S_OK) return hr; + + TRACE("new node type %d\n", type); + switch (type) + { + case NODE_DOCUMENT: + case NODE_DOCUMENT_TYPE: + case NODE_ENTITY: + case NODE_NOTATION: + if (old_node) *old_node = NULL; + return E_FAIL; + default: + return node_insert_before(&This->node, newNode, &refChild, old_node); + } } static HRESULT WINAPI domelem_replaceChild( @@ -739,7 +755,7 @@ static HRESULT encode_base64(const BYTE *buf, int len, BSTR *ret) { static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const BYTE *d = buf; - int bytes, pad_bytes, div, i; + int bytes, pad_bytes, div; DWORD needed; WCHAR *ptr; @@ -756,7 +772,6 @@ static HRESULT encode_base64(const BYTE *buf, int len, BSTR *ret) div = len / 3; ptr = *ret; - i = 0; while (div > 0) { /* first char is the first 6 bits of the first byte*/ @@ -769,7 +784,6 @@ static HRESULT encode_base64(const BYTE *buf, int len, BSTR *ret) *ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)]; /* fourth char is the remaining 6 bits of the third byte */ *ptr++ = b64[ d[2] & 0x3f]; - i += 4; d += 3; div--; } @@ -1232,8 +1246,7 @@ static HRESULT WINAPI domelem_setAttribute( domelem *This = impl_from_IXMLDOMElement( iface ); xmlChar *xml_name, *xml_value, *local, *prefix; xmlNodePtr element; - HRESULT hr; - VARIANT var; + HRESULT hr = S_OK; TRACE("(%p)->(%s %s)\n", This, debugstr_w(name), debugstr_variant(&value)); @@ -1241,16 +1254,25 @@ static HRESULT WINAPI domelem_setAttribute( if ( !element ) return E_FAIL; - VariantInit(&var); - hr = VariantChangeType(&var, &value, 0, VT_BSTR); - if(hr != S_OK) + if (V_VT(&value) != VT_BSTR) { - FIXME("VariantChangeType failed\n"); - return hr; + VARIANT var; + + VariantInit(&var); + hr = VariantChangeType(&var, &value, 0, VT_BSTR); + if (hr != S_OK) + { + FIXME("VariantChangeType failed\n"); + return hr; + } + + xml_value = xmlchar_from_wchar(V_BSTR(&var)); + VariantClear(&var); } + else + xml_value = xmlchar_from_wchar(V_BSTR(&value)); xml_name = xmlchar_from_wchar( name ); - xml_value = xmlchar_from_wchar( V_BSTR(&var) ); if ((local = xmlSplitQName2(xml_name, &prefix))) { @@ -1273,7 +1295,6 @@ static HRESULT WINAPI domelem_setAttribute( heap_free(xml_value); heap_free(xml_name); - VariantClear(&var); return hr; } diff --git a/reactos/dll/win32/msxml3/factory.c b/reactos/dll/win32/msxml3/factory.c index 6f82e183968..f22d08e23cd 100644 --- a/reactos/dll/win32/msxml3/factory.c +++ b/reactos/dll/win32/msxml3/factory.c @@ -101,7 +101,7 @@ static const struct clsid_version_t clsid_versions_table[] = static MSXML_VERSION get_msxml_version(const GUID *clsid) { - int i; + unsigned int i; for (i = 0; i < sizeof(clsid_versions_table)/sizeof(struct clsid_version_t); i++) if (IsEqualGUID(clsid, clsid_versions_table[i].clsid)) diff --git a/reactos/dll/win32/msxml3/httprequest.c b/reactos/dll/win32/msxml3/httprequest.c index 7ddc49cd72e..4179368839f 100644 --- a/reactos/dll/win32/msxml3/httprequest.c +++ b/reactos/dll/win32/msxml3/httprequest.c @@ -85,8 +85,8 @@ typedef struct /* request */ BINDVERB verb; BSTR custom; - BSTR siteurl; - BSTR url; + IUri *uri; + IUri *base_uri; BOOL async; struct list reqheaders; /* cached resulting custom request headers string length in WCHARs */ @@ -144,9 +144,17 @@ static inline serverhttp *impl_from_IServerXMLHTTPRequest(IServerXMLHTTPRequest static void httprequest_setreadystate(httprequest *This, READYSTATE state) { READYSTATE last = This->state; + static const char* readystates[] = { + "READYSTATE_UNINITIALIZED", + "READYSTATE_LOADING", + "READYSTATE_LOADED", + "READYSTATE_INTERACTIVE", + "READYSTATE_COMPLETE"}; This->state = state; + TRACE("state %s\n", readystates[state]); + if (This->sink && last != state) { DISPPARAMS params; @@ -209,6 +217,7 @@ static void BindStatusCallback_Detach(BindStatusCallback *bsc) if (bsc) { if (bsc->binding) IBinding_Abort(bsc->binding); + bsc->request->bsc = NULL; bsc->request = NULL; IBindStatusCallback_Release(&bsc->IBindStatusCallback_iface); } @@ -343,7 +352,11 @@ static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *ifac } if (hr == S_OK) + { + BindStatusCallback_Detach(This->request->bsc); + This->request->bsc = This; httprequest_setreadystate(This->request, READYSTATE_COMPLETE); + } return S_OK; } @@ -688,23 +701,28 @@ static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback * case VT_ARRAY|VT_UI1: { sa = V_ARRAY(body); - if ((hr = SafeArrayAccessData(sa, (void **)&ptr)) != S_OK) return hr; + if ((hr = SafeArrayAccessData(sa, (void **)&ptr)) != S_OK) + { + heap_free(bsc); + return hr; + } if ((hr = SafeArrayGetUBound(sa, 1, &size) != S_OK)) { SafeArrayUnaccessData(sa); + heap_free(bsc); return hr; } size++; break; } + default: + FIXME("unsupported body data type %d\n", V_VT(body)); + /* fall through */ case VT_EMPTY: case VT_ERROR: ptr = NULL; size = 0; break; - default: - FIXME("unsupported body data type %d\n", V_VT(body)); - break; } bsc->body = GlobalAlloc(GMEM_FIXED, size); @@ -734,7 +752,7 @@ static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback * { IMoniker *moniker; - hr = CreateURLMoniker(NULL, This->url, &moniker); + hr = CreateURLMonikerEx2(NULL, This->uri, &moniker, URL_MK_UNIFORM); if (hr == S_OK) { IStream *stream; @@ -756,6 +774,53 @@ static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback * return hr; } +static HRESULT verify_uri(httprequest *This, IUri *uri) +{ + DWORD scheme, base_scheme; + BSTR host, base_host; + HRESULT hr; + + if(!(This->safeopt & INTERFACESAFE_FOR_UNTRUSTED_DATA)) + return S_OK; + + if(!This->base_uri) + return E_ACCESSDENIED; + + hr = IUri_GetScheme(uri, &scheme); + if(FAILED(hr)) + return hr; + + hr = IUri_GetScheme(This->base_uri, &base_scheme); + if(FAILED(hr)) + return hr; + + if(scheme != base_scheme) { + WARN("Schemes don't match\n"); + return E_ACCESSDENIED; + } + + if(scheme == INTERNET_SCHEME_UNKNOWN) { + FIXME("Unknown scheme\n"); + return E_ACCESSDENIED; + } + + hr = IUri_GetHost(uri, &host); + if(FAILED(hr)) + return hr; + + hr = IUri_GetHost(This->base_uri, &base_host); + if(SUCCEEDED(hr)) { + if(strcmpiW(host, base_host)) { + WARN("Hosts don't match\n"); + hr = E_ACCESSDENIED; + } + SysFreeString(base_host); + } + + SysFreeString(host); + return hr; +} + static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url, VARIANT async, VARIANT user, VARIANT password) { @@ -765,15 +830,20 @@ static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url, static const WCHAR MethodDeleteW[] = {'D','E','L','E','T','E',0}; static const WCHAR MethodPropFindW[] = {'P','R','O','P','F','I','N','D',0}; VARIANT str, is_async; + IUri *uri; HRESULT hr; if (!method || !url) return E_INVALIDARG; /* free previously set data */ - SysFreeString(This->url); + if(This->uri) { + IUri_Release(This->uri); + This->uri = NULL; + } + SysFreeString(This->user); SysFreeString(This->password); - This->url = This->user = This->password = NULL; + This->user = This->password = NULL; if (!strcmpiW(method, MethodGetW)) { @@ -800,22 +870,22 @@ static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url, return E_FAIL; } - /* try to combine with site url */ - if (This->siteurl && PathIsRelativeW(url)) - { - DWORD len = INTERNET_MAX_URL_LENGTH; - WCHAR *fullW = heap_alloc(len*sizeof(WCHAR)); - - hr = UrlCombineW(This->siteurl, url, fullW, &len, 0); - if (hr == S_OK) - { - TRACE("combined url %s\n", debugstr_w(fullW)); - This->url = SysAllocString(fullW); - } - heap_free(fullW); - } + if(This->base_uri) + hr = CoInternetCombineUrlEx(This->base_uri, url, 0, &uri, 0); else - This->url = SysAllocString(url); + hr = CreateUri(url, 0, 0, &uri); + if(FAILED(hr)) { + WARN("Could not create IUri object: %08x\n", hr); + return hr; + } + + hr = verify_uri(This, uri); + if(FAILED(hr)) { + IUri_Release(uri); + return hr; + } + + This->uri = uri; VariantInit(&is_async); hr = VariantChangeType(&is_async, &async, 0, VT_BOOL); @@ -881,7 +951,8 @@ static HRESULT httprequest_getResponseHeader(httprequest *This, BSTR header, BST { struct httpheader *entry; - if (!header || !value) return E_INVALIDARG; + if (!header) return E_INVALIDARG; + if (!value) return E_POINTER; if (This->raw_respheaders && list_empty(&This->respheaders)) { @@ -915,7 +986,7 @@ static HRESULT httprequest_getResponseHeader(httprequest *This, BSTR header, BST static HRESULT httprequest_getAllResponseHeaders(httprequest *This, BSTR *respheaders) { - if (!respheaders) return E_INVALIDARG; + if (!respheaders) return E_POINTER; *respheaders = SysAllocString(This->raw_respheaders); @@ -930,10 +1001,9 @@ static HRESULT httprequest_send(httprequest *This, VARIANT body) if (This->state != READYSTATE_LOADING) return E_FAIL; hr = BindStatusCallback_create(This, &bsc, &body); - if (FAILED(hr)) return hr; - - BindStatusCallback_Detach(This->bsc); - This->bsc = bsc; + if (FAILED(hr)) + /* success path to detach it is OnStopBinding call */ + BindStatusCallback_Detach(bsc); return hr; } @@ -941,7 +1011,6 @@ static HRESULT httprequest_send(httprequest *This, VARIANT body) static HRESULT httprequest_abort(httprequest *This) { BindStatusCallback_Detach(This->bsc); - This->bsc = NULL; httprequest_setreadystate(This, READYSTATE_UNINITIALIZED); @@ -950,17 +1019,16 @@ static HRESULT httprequest_abort(httprequest *This) static HRESULT httprequest_get_status(httprequest *This, LONG *status) { - if (!status) return E_INVALIDARG; - if (This->state != READYSTATE_COMPLETE) return E_FAIL; + if (!status) return E_POINTER; *status = This->status; - return S_OK; + return This->state == READYSTATE_COMPLETE ? S_OK : E_FAIL; } static HRESULT httprequest_get_statusText(httprequest *This, BSTR *status) { - if (!status) return E_INVALIDARG; + if (!status) return E_POINTER; if (This->state != READYSTATE_COMPLETE) return E_FAIL; *status = SysAllocString(This->status_text); @@ -973,7 +1041,7 @@ static HRESULT httprequest_get_responseText(httprequest *This, BSTR *body) HGLOBAL hglobal; HRESULT hr; - if (!body) return E_INVALIDARG; + if (!body) return E_POINTER; if (This->state != READYSTATE_COMPLETE) return E_FAIL; hr = GetHGlobalFromStream(This->bsc->stream, &hglobal); @@ -1119,7 +1187,7 @@ static HRESULT httprequest_get_responseStream(httprequest *This, VARIANT *body) static HRESULT httprequest_get_readyState(httprequest *This, LONG *state) { - if (!state) return E_INVALIDARG; + if (!state) return E_POINTER; *state = This->state; return S_OK; @@ -1139,10 +1207,12 @@ static void httprequest_release(httprequest *This) if (This->site) IUnknown_Release( This->site ); + if (This->uri) + IUri_Release(This->uri); + if (This->base_uri) + IUri_Release(This->base_uri); SysFreeString(This->custom); - SysFreeString(This->siteurl); - SysFreeString(This->url); SysFreeString(This->user); SysFreeString(This->password); @@ -1442,37 +1512,55 @@ static HRESULT WINAPI httprequest_ObjectWithSite_GetSite( IObjectWithSite *iface return IUnknown_QueryInterface( This->site, iid, ppvSite ); } +static void get_base_uri(httprequest *This) +{ + IServiceProvider *provider; + IHTMLDocument2 *doc; + IUri *uri; + BSTR url; + HRESULT hr; + + hr = IUnknown_QueryInterface(This->site, &IID_IServiceProvider, (void**)&provider); + if(FAILED(hr)) + return; + + hr = IServiceProvider_QueryService(provider, &SID_SContainerDispatch, &IID_IHTMLDocument2, (void**)&doc); + IServiceProvider_Release(provider); + if(FAILED(hr)) + return; + + hr = IHTMLDocument2_get_URL(doc, &url); + IHTMLDocument2_Release(doc); + if(FAILED(hr) || !url || !*url) + return; + + TRACE("host url %s\n", debugstr_w(url)); + + hr = CreateUri(url, 0, 0, &uri); + SysFreeString(url); + if(FAILED(hr)) + return; + + This->base_uri = uri; +} + static HRESULT WINAPI httprequest_ObjectWithSite_SetSite( IObjectWithSite *iface, IUnknown *punk ) { httprequest *This = impl_from_IObjectWithSite(iface); - IServiceProvider *provider; - HRESULT hr; - TRACE("(%p)->(%p)\n", iface, punk); - - if (punk) - IUnknown_AddRef( punk ); + TRACE("(%p)->(%p)\n", This, punk); if(This->site) IUnknown_Release( This->site ); + if(This->base_uri) + IUri_Release(This->base_uri); This->site = punk; - hr = IUnknown_QueryInterface(This->site, &IID_IServiceProvider, (void**)&provider); - if (hr == S_OK) + if (punk) { - IHTMLDocument2 *doc; - - hr = IServiceProvider_QueryService(provider, &SID_SContainerDispatch, &IID_IHTMLDocument2, (void**)&doc); - if (hr == S_OK) - { - SysFreeString(This->siteurl); - - hr = IHTMLDocument2_get_URL(doc, &This->siteurl); - IHTMLDocument2_Release(doc); - TRACE("host url %s, 0x%08x\n", debugstr_w(This->siteurl), hr); - } - IServiceProvider_Release(provider); + IUnknown_AddRef( punk ); + get_base_uri(This); } return S_OK; @@ -1826,7 +1914,8 @@ static void init_httprequest(httprequest *req) req->async = FALSE; req->verb = -1; req->custom = NULL; - req->url = req->siteurl = req->user = req->password = NULL; + req->uri = req->base_uri = NULL; + req->user = req->password = NULL; req->state = READYSTATE_UNINITIALIZED; req->sink = NULL; diff --git a/reactos/dll/win32/msxml3/main.c b/reactos/dll/win32/msxml3/main.c index 4deee6a3033..4f18378876a 100644 --- a/reactos/dll/win32/msxml3/main.c +++ b/reactos/dll/win32/msxml3/main.c @@ -276,6 +276,8 @@ const char *debugstr_variant(const VARIANT *v) return wine_dbg_sprintf("{VT_I2: %d}", V_I2(v)); case VT_I4: return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v)); + case VT_INT: + return wine_dbg_sprintf("{VT_INT: %d}", V_INT(v)); case VT_R8: return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v)); case VT_BSTR: diff --git a/reactos/dll/win32/msxml3/msxml_private.h b/reactos/dll/win32/msxml3/msxml_private.h index e156ec26703..dc5250bb132 100644 --- a/reactos/dll/win32/msxml3/msxml_private.h +++ b/reactos/dll/win32/msxml3/msxml_private.h @@ -194,7 +194,8 @@ static inline LPWSTR heap_strdupW(LPCWSTR str) size = (strlenW(str)+1)*sizeof(WCHAR); ret = heap_alloc(size); - memcpy(ret, str, size); + if(ret) + memcpy(ret, str, size); } return ret; @@ -291,6 +292,9 @@ extern xmlChar *xmlChar_from_wchar( LPCWSTR str ) DECLSPEC_HIDDEN; extern void xmldoc_init( xmlDocPtr doc, MSXML_VERSION version ) DECLSPEC_HIDDEN; extern LONG xmldoc_add_ref( xmlDocPtr doc ) DECLSPEC_HIDDEN; extern LONG xmldoc_release( xmlDocPtr doc ) DECLSPEC_HIDDEN; +extern LONG xmldoc_add_refs( xmlDocPtr doc, LONG refs ) DECLSPEC_HIDDEN; +extern LONG xmldoc_release_refs ( xmlDocPtr doc, LONG refs ) DECLSPEC_HIDDEN; +extern int xmlnode_get_inst_cnt( xmlnode *node ) DECLSPEC_HIDDEN; extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node ) DECLSPEC_HIDDEN; extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node ) DECLSPEC_HIDDEN; extern void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node) DECLSPEC_HIDDEN; @@ -404,6 +408,21 @@ static inline xmlChar *xmlchar_from_wchar( const WCHAR *str ) return xmlchar_from_wcharn(str, -1); } +static inline xmlChar *heap_strdupxmlChar(const xmlChar *str) +{ + xmlChar *ret = NULL; + + if(str) { + DWORD size; + + size = (xmlStrlen(str)+1)*sizeof(xmlChar); + ret = heap_alloc(size); + memcpy(ret, str, size); + } + + return ret; +} + #endif static inline HRESULT return_bstr(const WCHAR *value, BSTR *p) diff --git a/reactos/dll/win32/msxml3/mxwriter.c b/reactos/dll/win32/msxml3/mxwriter.c index 0069e4119b6..e60a6074069 100644 --- a/reactos/dll/win32/msxml3/mxwriter.c +++ b/reactos/dll/win32/msxml3/mxwriter.c @@ -291,7 +291,9 @@ static HRESULT alloc_output_buffer(xml_encoding encoding, output_buffer **buffer return hr; } - if (ret->code_page == CP_UTF8) { + /* currently we always create a default output buffer that is UTF-16 only, + but it's possible to allocate with specific encoding too */ + if (encoding != XmlEncoding_UTF16) { hr = init_encoded_buffer(&ret->encoded); if (hr != S_OK) { free_encoded_buffer(&ret->utf16); diff --git a/reactos/dll/win32/msxml3/node.c b/reactos/dll/win32/msxml3/node.c index 788bea8bd32..f52026e8668 100644 --- a/reactos/dll/win32/msxml3/node.c +++ b/reactos/dll/win32/msxml3/node.c @@ -285,36 +285,48 @@ static HRESULT node_set_content_escaped(xmlnode *This, LPCWSTR value) HRESULT node_put_value(xmlnode *This, VARIANT *value) { - VARIANT string_value; HRESULT hr; - VariantInit(&string_value); - hr = VariantChangeType(&string_value, value, 0, VT_BSTR); - if(FAILED(hr)) { - WARN("Couldn't convert to VT_BSTR\n"); - return hr; - } + if (V_VT(value) != VT_BSTR) + { + VARIANT string_value; - hr = node_set_content(This, V_BSTR(&string_value)); - VariantClear(&string_value); + VariantInit(&string_value); + hr = VariantChangeType(&string_value, value, 0, VT_BSTR); + if(FAILED(hr)) { + WARN("Couldn't convert to VT_BSTR\n"); + return hr; + } + + hr = node_set_content(This, V_BSTR(&string_value)); + VariantClear(&string_value); + } + else + hr = node_set_content(This, V_BSTR(value)); return hr; } HRESULT node_put_value_escaped(xmlnode *This, VARIANT *value) { - VARIANT string_value; HRESULT hr; - VariantInit(&string_value); - hr = VariantChangeType(&string_value, value, 0, VT_BSTR); - if(FAILED(hr)) { - WARN("Couldn't convert to VT_BSTR\n"); - return hr; - } + if (V_VT(value) != VT_BSTR) + { + VARIANT string_value; - hr = node_set_content_escaped(This, V_BSTR(&string_value)); - VariantClear(&string_value); + VariantInit(&string_value); + hr = VariantChangeType(&string_value, value, 0, VT_BSTR); + if(FAILED(hr)) { + WARN("Couldn't convert to VT_BSTR\n"); + return hr; + } + + hr = node_set_content_escaped(This, V_BSTR(&string_value)); + VariantClear(&string_value); + } + else + hr = node_set_content_escaped(This, V_BSTR(value)); return hr; } @@ -377,11 +389,45 @@ HRESULT node_get_next_sibling(xmlnode *This, IXMLDOMNode **ret) return get_node(This, "next", This->node->next, ret); } +static int node_get_inst_cnt(xmlNodePtr node) +{ + int ret = *(LONG *)&node->_private; + xmlNodePtr child; + + /* add attribute counts */ + if (node->type == XML_ELEMENT_NODE) + { + xmlAttrPtr prop = node->properties; + + while (prop) + { + ret += node_get_inst_cnt((xmlNodePtr)prop); + prop = prop->next; + } + } + + /* add children counts */ + child = node->children; + while (child) + { + ret += node_get_inst_cnt(child); + child = child->next; + } + + return ret; +} + +int xmlnode_get_inst_cnt(xmlnode *node) +{ + return node_get_inst_cnt(node->node); +} + HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT *ref_child, IXMLDOMNode **ret) { IXMLDOMNode *before = NULL; xmlnode *node_obj; + int refcount = 0; xmlDocPtr doc; HRESULT hr; @@ -417,6 +463,8 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT if(xmldoc_remove_orphan(node_obj->node->doc, node_obj->node) != S_OK) WARN("%p is not an orphan of %p\n", node_obj->node, node_obj->node->doc); + refcount = xmlnode_get_inst_cnt(node_obj); + if(before) { xmlnode *before_node_obj = get_node_obj(before); @@ -429,10 +477,16 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT hr = IXMLDOMNode_removeChild(node_obj->parent, node_obj->iface, NULL); if (hr == S_OK) xmldoc_remove_orphan(node_obj->node->doc, node_obj->node); } + doc = node_obj->node->doc; - xmldoc_add_ref(before_node_obj->node->doc); + + /* refs count including subtree */ + if (doc != before_node_obj->node->doc) + refcount = xmlnode_get_inst_cnt(node_obj); + + if (refcount) xmldoc_add_refs(before_node_obj->node->doc, refcount); xmlAddPrevSibling(before_node_obj->node, node_obj->node); - xmldoc_release(doc); + if (refcount) xmldoc_release_refs(doc, refcount); node_obj->parent = This->parent; } else @@ -444,11 +498,15 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT if (hr == S_OK) xmldoc_remove_orphan(node_obj->node->doc, node_obj->node); } doc = node_obj->node->doc; - xmldoc_add_ref(This->node->doc); + + if (doc != This->node->doc) + refcount = xmlnode_get_inst_cnt(node_obj); + + if (refcount) xmldoc_add_refs(This->node->doc, refcount); /* xmlAddChild doesn't unlink node from previous parent */ xmlUnlinkNode(node_obj->node); xmlAddChild(This->node, node_obj->node); - xmldoc_release(doc); + if (refcount) xmldoc_release_refs(doc, refcount); node_obj->parent = This->iface; } @@ -468,6 +526,7 @@ HRESULT node_replace_child(xmlnode *This, IXMLDOMNode *newChild, IXMLDOMNode *ol xmlnode *old_child, *new_child; xmlDocPtr leaving_doc; xmlNode *my_ancestor; + int refcount = 0; /* Do not believe any documentation telling that newChild == NULL means removal. It does certainly *not* apply to msxml3! */ @@ -505,9 +564,13 @@ HRESULT node_replace_child(xmlnode *This, IXMLDOMNode *newChild, IXMLDOMNode *ol WARN("%p is not an orphan of %p\n", new_child->node, new_child->node->doc); leaving_doc = new_child->node->doc; - xmldoc_add_ref(old_child->node->doc); + + if (leaving_doc != old_child->node->doc) + refcount = xmlnode_get_inst_cnt(new_child); + + if (refcount) xmldoc_add_refs(old_child->node->doc, refcount); xmlReplaceNode(old_child->node, new_child->node); - xmldoc_release(leaving_doc); + if (refcount) xmldoc_release_refs(leaving_doc, refcount); new_child->parent = old_child->parent; old_child->parent = NULL; @@ -598,7 +661,7 @@ HRESULT node_clone(xmlnode *This, VARIANT_BOOL deep, IXMLDOMNode **cloneNode) clone = xmlCopyNode(This->node, deep ? 1 : 2); if (clone) { - clone->doc = This->node->doc; + xmlSetTreeDoc(clone, This->node->doc); xmldoc_add_orphan(clone->doc, clone); node = create_node(clone); @@ -836,6 +899,53 @@ HRESULT node_get_xml(xmlnode *This, BOOL ensure_eol, BSTR *ret) return *ret ? S_OK : E_OUTOFMEMORY; } +static void htmldtd_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc) +{ + xmlDtdPtr cur = doc->intSubset; + + xmlOutputBufferWriteString(buf, "name); + if (cur->ExternalID) + { + xmlOutputBufferWriteString(buf, " PUBLIC "); + xmlBufferWriteQuotedString(buf->buffer, cur->ExternalID); + if (cur->SystemID) + { + xmlOutputBufferWriteString(buf, " "); + xmlBufferWriteQuotedString(buf->buffer, cur->SystemID); + } + } + else if (cur->SystemID) + { + xmlOutputBufferWriteString(buf, " SYSTEM "); + xmlBufferWriteQuotedString(buf->buffer, cur->SystemID); + } + xmlOutputBufferWriteString(buf, ">\n"); +} + +static void htmldoc_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc) +{ + xmlElementType type; + + /* force HTML output */ + type = doc->type; + doc->type = XML_HTML_DOCUMENT_NODE; + if (doc->intSubset) + htmldtd_dumpcontent(buf, doc); + if (doc->children) + { + xmlNodePtr cur = doc->children; + + while (cur) + { + htmlNodeDumpFormatOutput(buf, doc, cur, NULL, 1); + cur = cur->next; + } + + } + doc->type = type; +} + HRESULT node_transform_node(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR *p) { #ifdef SONAME_LIBXSLT @@ -863,7 +973,7 @@ HRESULT node_transform_node(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR * xmlOutputBufferPtr output = xmlAllocOutputBuffer(NULL); if (output) { - htmlDocContentDumpOutput(output, result->doc, NULL); + htmldoc_dumpcontent(output, result->doc); content = xmlBufferContent(output->buffer); *p = bstr_from_xmlChar(content); xmlOutputBufferClose(output); @@ -973,17 +1083,36 @@ HRESULT node_get_base_name(xmlnode *This, BSTR *name) return S_OK; } +/* _private field holds a number of COM instances spawned from this libxml2 node */ +static void xmlnode_add_ref(xmlNodePtr node) +{ + if (node->type == XML_DOCUMENT_NODE) return; + InterlockedIncrement((LONG*)&node->_private); +} + +static void xmlnode_release(xmlNodePtr node) +{ + if (node->type == XML_DOCUMENT_NODE) return; + InterlockedDecrement((LONG*)&node->_private); +} + void destroy_xmlnode(xmlnode *This) { if(This->node) + { + xmlnode_release(This->node); xmldoc_release(This->node->doc); + } release_dispex(&This->dispex); } void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispex_static_data_t *dispex_data) { if(node) - xmldoc_add_ref( node->doc ); + { + xmlnode_add_ref(node); + xmldoc_add_ref(node->doc); + } This->node = node; This->iface = node_iface; diff --git a/reactos/dll/win32/msxml3/nodelist.c b/reactos/dll/win32/msxml3/nodelist.c index 6ed73de22d9..994d5b93921 100644 --- a/reactos/dll/win32/msxml3/nodelist.c +++ b/reactos/dll/win32/msxml3/nodelist.c @@ -341,28 +341,62 @@ static HRESULT xmlnodelist_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fl TRACE("(%p)->(%x %x %x %p %p %p)\n", This, id, lcid, flags, params, res, ei); - V_VT(res) = VT_DISPATCH; - V_DISPATCH(res) = NULL; - - if (id < DISPID_DOM_COLLECTION_BASE || id > DISPID_DOM_COLLECTION_MAX) - return DISP_E_UNKNOWNNAME; - - switch(flags) + if (id >= DISPID_DOM_COLLECTION_BASE && id <= DISPID_DOM_COLLECTION_MAX) { - case INVOKE_PROPERTYGET: + switch(flags) { - IXMLDOMNode *disp = NULL; + case DISPATCH_PROPERTYGET: + { + IXMLDOMNode *disp = NULL; - IXMLDOMNodeList_get_item(&This->IXMLDOMNodeList_iface, id - DISPID_DOM_COLLECTION_BASE, &disp); - V_DISPATCH(res) = (IDispatch*)disp; - break; - } - default: - { - FIXME("unimplemented flags %x\n", flags); - break; + V_VT(res) = VT_DISPATCH; + IXMLDOMNodeList_get_item(&This->IXMLDOMNodeList_iface, id - DISPID_DOM_COLLECTION_BASE, &disp); + V_DISPATCH(res) = (IDispatch*)disp; + break; + } + default: + { + FIXME("unimplemented flags %x\n", flags); + break; + } } } + else if (id == DISPID_VALUE) + { + switch(flags) + { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + case DISPATCH_PROPERTYGET: + case DISPATCH_METHOD: + { + IXMLDOMNode *item; + VARIANT index; + HRESULT hr; + + if (params->cArgs - params->cNamedArgs != 1) return DISP_E_BADPARAMCOUNT; + + VariantInit(&index); + hr = VariantChangeType(&index, params->rgvarg, 0, VT_I4); + if(FAILED(hr)) + { + FIXME("failed to convert arg, %s\n", debugstr_variant(params->rgvarg)); + return hr; + } + + IXMLDOMNodeList_get_item(&This->IXMLDOMNodeList_iface, V_I4(&index), &item); + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)item; + break; + } + default: + { + FIXME("DISPID_VALUE: unimplemented flags %x\n", flags); + break; + } + } + } + else + return DISP_E_UNKNOWNNAME; TRACE("ret %p\n", V_DISPATCH(res)); diff --git a/reactos/dll/win32/msxml3/saxreader.c b/reactos/dll/win32/msxml3/saxreader.c index 19d8e69a5fa..9fb17120423 100644 --- a/reactos/dll/win32/msxml3/saxreader.c +++ b/reactos/dll/win32/msxml3/saxreader.c @@ -171,12 +171,13 @@ enum saxhandler_type SAXContentHandler = 0, SAXDeclHandler, SAXDTDHandler, + SAXEntityResolver, SAXErrorHandler, SAXLexicalHandler, SAXHandler_Last }; -struct saxhandler_iface +struct saxanyhandler_iface { IUnknown *handler; IUnknown *vbhandler; @@ -200,6 +201,23 @@ struct saxlexicalhandler_iface IVBSAXLexicalHandler *vbhandler; }; +struct saxentityresolver_iface +{ + ISAXEntityResolver *handler; + IVBSAXEntityResolver *vbhandler; +}; + +struct saxhandler_iface +{ + union { + struct saxcontenthandler_iface content; + struct saxentityresolver_iface entityresolver; + struct saxerrorhandler_iface error; + struct saxlexicalhandler_iface lexical; + struct saxanyhandler_iface anyhandler; + } u; +}; + typedef struct { DispatchEx dispex; @@ -218,7 +236,7 @@ typedef struct static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb) { - struct saxhandler_iface *iface = &reader->saxhandlers[type]; + struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler; IUnknown *unk = (IUnknown*)ptr; if (unk) @@ -237,7 +255,7 @@ static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type typ static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret) { - const struct saxhandler_iface *iface = &reader->saxhandlers[type]; + const struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler; if (!ret) return E_POINTER; @@ -256,17 +274,17 @@ static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_ty static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader) { - return (struct saxcontenthandler_iface*)&reader->saxhandlers[SAXContentHandler]; + return &reader->saxhandlers[SAXContentHandler].u.content; } static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader) { - return (struct saxerrorhandler_iface*)&reader->saxhandlers[SAXErrorHandler]; + return &reader->saxhandlers[SAXErrorHandler].u.error; } static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader) { - return (struct saxlexicalhandler_iface*)&reader->saxhandlers[SAXLexicalHandler]; + return &reader->saxhandlers[SAXLexicalHandler].u.lexical; } typedef struct @@ -279,8 +297,8 @@ typedef struct saxreader *saxreader; HRESULT ret; xmlParserCtxtPtr pParserCtxt; - WCHAR *publicId; - WCHAR *systemId; + BSTR publicId; + BSTR systemId; int line; int column; BOOL vbInterface; @@ -330,8 +348,23 @@ static inline saxlocator *impl_from_ISAXAttributes( ISAXAttributes *iface ) static inline int saxreader_has_handler(const saxlocator *locator, enum saxhandler_type type) { - return (locator->vbInterface && locator->saxreader->saxhandlers[type].vbhandler) || - (!locator->vbInterface && locator->saxreader->saxhandlers[type].handler); + struct saxanyhandler_iface *iface = &locator->saxreader->saxhandlers[type].u.anyhandler; + return (locator->vbInterface && iface->vbhandler) || (!locator->vbInterface && iface->handler); +} + +static HRESULT saxreader_saxcharacters(saxlocator *locator, BSTR chars) +{ + struct saxcontenthandler_iface *content = saxreader_get_contenthandler(locator->saxreader); + HRESULT hr; + + if (!saxreader_has_handler(locator, SAXContentHandler)) return S_OK; + + if (locator->vbInterface) + hr = IVBSAXContentHandler_characters(content->vbhandler, &chars); + else + hr = ISAXContentHandler_characters(content->handler, chars, SysStringLen(chars)); + + return hr; } /* property names */ @@ -1550,7 +1583,6 @@ static void libxmlCharacters( int len) { saxlocator *This = ctx; - struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader); BSTR Chars; HRESULT hr; xmlChar *cur, *end; @@ -1609,10 +1641,7 @@ static void libxmlCharacters( } Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur); - if(This->vbInterface) - hr = IVBSAXContentHandler_characters(handler->vbhandler, &Chars); - else - hr = ISAXContentHandler_characters(handler->handler, Chars, SysStringLen(Chars)); + hr = saxreader_saxcharacters(This, Chars); if (sax_callback_failed(This, hr)) { @@ -1745,33 +1774,58 @@ static void libxmlFatalError(void *ctx, const char *msg, ...) This->ret = E_FAIL; } -static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len) +/* The only reason this helper exists is that CDATA section are reported by chunks, + newlines are used as delimiter. More than that, reader even alters input data before reporting. + + This helper should be called for substring with trailing newlines. +*/ +static BSTR saxreader_get_cdata_chunk(const xmlChar *str, int len) { - saxlocator *This = ctx; - struct saxcontenthandler_iface *content = saxreader_get_contenthandler(This->saxreader); - struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(This->saxreader); - HRESULT hr = S_OK; - xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur-len; - xmlChar *cur, *end; - int realLen; - BSTR Chars; - BOOL lastEvent = FALSE, change; + BSTR bstr = bstr_from_xmlCharN(str, len), ret; + WCHAR *ptr; - update_position(This, FALSE); - while(beg-9>=This->pParserCtxt->input->base - && memcmp(beg-9, "= bstr) + ptr--; + + while (*++ptr) { - if(*beg=='\n' || (*beg=='\r' && *(beg+1)!='\n')) - This->line--; - beg--; + /* replace returns as: + + - "\r" -> "\n" + - "\r\r" -> "\r" + - "\r\n" -> "\n" + */ + if (*ptr == '\r') + { + if (*(ptr+1) == '\r' || *(ptr+1) == '\n') + { + /* shift tail */ + memmove(ptr, ptr+1, len-- - (ptr-bstr)); + } + else + *ptr = '\n'; + } } - This->column = 0; - for(; beg>=This->pParserCtxt->input->base && *beg!='\n' && *beg!='\r'; beg--) - This->column++; - if (saxreader_has_handler(This, SAXLexicalHandler)) + ret = SysAllocStringLen(bstr, len); + SysFreeString(bstr); + return ret; +} + +static void libxml_cdatablock(void *ctx, const xmlChar *value, int len) +{ + const xmlChar *start, *end; + saxlocator *locator = ctx; + struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader); + HRESULT hr = S_OK; + BSTR chars; + int i; + + update_position(locator, FALSE); + if (saxreader_has_handler(locator, SAXLexicalHandler)) { - if (This->vbInterface) + if (locator->vbInterface) hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler); else hr = ISAXLexicalHandler_startCDATA(lexical->handler); @@ -1779,61 +1833,66 @@ static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len) if(FAILED(hr)) { - format_error_message_from_id(This, hr); + format_error_message_from_id(locator, hr); return; } - realLen = This->pParserCtxt->input->cur-beg-3; - cur = beg; - end = beg; + start = value; + end = NULL; + i = 0; - while(1) + while (i < len) { - while(end-begsaxreader->pool, cur, end-cur+1); - if (This->vbInterface) - hr = IVBSAXContentHandler_characters(content->vbhandler, &Chars); - else - hr = ISAXContentHandler_characters(content->handler, Chars, SysStringLen(Chars)); - } - - if(change) *end = '\r'; - - if(lastEvent) - break; - - This->column += end-cur+2; - end += 2; - cur = end; + i++; + locator->column++; } - if (saxreader_has_handler(This, SAXLexicalHandler)) + /* no newline chars (or last chunk) report as a whole */ + if (!end && start == value) { - if (This->vbInterface) + /* report */ + chars = bstr_from_xmlCharN(start, len-(start-value)); + TRACE("(%s)\n", debugstr_w(chars)); + hr = saxreader_saxcharacters(locator, chars); + SysFreeString(chars); + } + + if (saxreader_has_handler(locator, SAXLexicalHandler)) + { + if (locator->vbInterface) hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler); else hr = ISAXLexicalHandler_endCDATA(lexical->handler); } if(FAILED(hr)) - format_error_message_from_id(This, hr); + format_error_message_from_id(locator, hr); +} - This->column += 4+end-cur; +static xmlParserInputPtr libxmlresolveentity(void *ctx, const xmlChar *publicid, const xmlChar *systemid) +{ + FIXME("entity resolving not implemented, %s, %s\n", publicid, systemid); + return xmlSAX2ResolveEntity(ctx, publicid, systemid); } /*** IVBSAXLocator interface ***/ @@ -2123,7 +2182,7 @@ static HRESULT WINAPI isaxlocator_getPublicId( publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt)); if(SysStringLen(publicId)) - This->publicId = (WCHAR*)&publicId; + This->publicId = publicId; else { SysFreeString(publicId); @@ -2145,7 +2204,7 @@ static HRESULT WINAPI isaxlocator_getSystemId( systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt)); if(SysStringLen(systemId)) - This->systemId = (WCHAR*)&systemId; + This->systemId = systemId; else { SysFreeString(systemId); @@ -2370,24 +2429,6 @@ static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream, return hr; } -static HRESULT internal_getEntityResolver( - saxreader *This, - void *pEntityResolver, - BOOL vbInterface) -{ - FIXME("(%p)->(%p) stub\n", This, pEntityResolver); - return E_NOTIMPL; -} - -static HRESULT internal_putEntityResolver( - saxreader *This, - void *pEntityResolver, - BOOL vbInterface) -{ - FIXME("(%p)->(%p) stub\n", This, pEntityResolver); - return E_NOTIMPL; -} - static HRESULT internal_parse( saxreader* This, VARIANT varInput, @@ -2737,7 +2778,7 @@ static ULONG WINAPI saxxmlreader_Release( for (i = 0; i < SAXHandler_Last; i++) { - struct saxhandler_iface *iface = &This->saxhandlers[i]; + struct saxanyhandler_iface *iface = &This->saxhandlers[i].u.anyhandler; if (iface->handler) IUnknown_Release(iface->handler); @@ -2870,18 +2911,18 @@ static HRESULT WINAPI saxxmlreader_putProperty( static HRESULT WINAPI saxxmlreader_get_entityResolver( IVBSAXXMLReader* iface, - IVBSAXEntityResolver **pEntityResolver) + IVBSAXEntityResolver **resolver) { saxreader *This = impl_from_IVBSAXXMLReader( iface ); - return internal_getEntityResolver(This, pEntityResolver, TRUE); + return saxreader_get_handler(This, SAXEntityResolver, TRUE, (void**)resolver); } static HRESULT WINAPI saxxmlreader_put_entityResolver( IVBSAXXMLReader* iface, - IVBSAXEntityResolver *pEntityResolver) + IVBSAXEntityResolver *resolver) { saxreader *This = impl_from_IVBSAXXMLReader( iface ); - return internal_putEntityResolver(This, pEntityResolver, TRUE); + return saxreader_put_handler(This, SAXEntityResolver, resolver, TRUE); } static HRESULT WINAPI saxxmlreader_get_contentHandler( @@ -3077,18 +3118,18 @@ static HRESULT WINAPI isaxxmlreader_putProperty( static HRESULT WINAPI isaxxmlreader_getEntityResolver( ISAXXMLReader* iface, - ISAXEntityResolver **ppEntityResolver) + ISAXEntityResolver **resolver) { saxreader *This = impl_from_ISAXXMLReader( iface ); - return internal_getEntityResolver(This, ppEntityResolver, FALSE); + return saxreader_get_handler(This, SAXEntityResolver, FALSE, (void**)resolver); } static HRESULT WINAPI isaxxmlreader_putEntityResolver( ISAXXMLReader* iface, - ISAXEntityResolver *pEntityResolver) + ISAXEntityResolver *resolver) { saxreader *This = impl_from_ISAXXMLReader( iface ); - return internal_putEntityResolver(This, pEntityResolver, FALSE); + return saxreader_put_handler(This, SAXEntityResolver, resolver, FALSE); } static HRESULT WINAPI isaxxmlreader_getContentHandler( @@ -3256,7 +3297,8 @@ HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *outer, LPVOID *ppOb reader->sax.comment = libxmlComment; reader->sax.error = libxmlFatalError; reader->sax.fatalError = libxmlFatalError; - reader->sax.cdataBlock = libxmlCDataBlock; + reader->sax.cdataBlock = libxml_cdatablock; + reader->sax.resolveEntity = libxmlresolveentity; *ppObj = &reader->IVBSAXXMLReader_iface; diff --git a/reactos/dll/win32/msxml3/schema.c b/reactos/dll/win32/msxml3/schema.c index f0413842e50..f00ba3a3b45 100644 --- a/reactos/dll/win32/msxml3/schema.c +++ b/reactos/dll/win32/msxml3/schema.c @@ -103,6 +103,9 @@ typedef struct MSXML_VERSION version; xmlHashTablePtr cache; + xmlChar **uris; + int allocated; + int count; VARIANT_BOOL validateOnLoad; int read_only; @@ -116,12 +119,6 @@ typedef struct LONG ref; } cache_entry; -typedef struct -{ - LONG index; - BSTR* out; -} cache_index_data; - /* datatypes lookup stuff * generated with help from gperf */ #define DT_MIN_STR_LEN 2 @@ -744,7 +741,7 @@ void schemasInit(void) return; } buf = LockResource(datatypes_handle); - datatypes_len = SizeofResource(MSXML_hInstance, datatypes_rsrc) - 1; + datatypes_len = SizeofResource(MSXML_hInstance, datatypes_rsrc); /* Resource is loaded as raw data, * need a null-terminated string */ @@ -844,7 +841,7 @@ static BOOL link_datatypes(xmlDocPtr schema) xmlNodePtr root, next, child; xmlNsPtr ns; - assert((void*)xmlGetExternalEntityLoader() == (void*)external_entity_loader); + assert(xmlGetExternalEntityLoader() == external_entity_loader); root = xmlDocGetRootElement(schema); if (!root) return FALSE; @@ -985,6 +982,55 @@ static void cache_free(void* data, xmlChar* name /* ignored */) cache_entry_release((cache_entry*)data); } +/* returns index or -1 if not found */ +static int cache_free_uri(schema_cache *cache, const xmlChar *uri) +{ + int i; + + for (i = 0; i < cache->count; i++) + if (xmlStrEqual(cache->uris[i], uri)) + { + heap_free(cache->uris[i]); + return i; + } + + return -1; +} + +static void cache_add_entry(schema_cache *cache, const xmlChar *uri, cache_entry *entry) +{ + int i; + + /* meaning no entry found with this name */ + if (xmlHashRemoveEntry(cache->cache, uri, cache_free)) + { + if (cache->count == cache->allocated) + { + cache->allocated *= 2; + cache->uris = heap_realloc(cache->uris, cache->allocated*sizeof(xmlChar*)); + } + i = cache->count++; + } + else + i = cache_free_uri(cache, uri); + + cache->uris[i] = heap_strdupxmlChar(uri); + xmlHashAddEntry(cache->cache, uri, entry); +} + +static void cache_remove_entry(schema_cache *cache, const xmlChar *uri) +{ + /* adjust index if entry was really removed */ + if (xmlHashRemoveEntry(cache->cache, uri, cache_free) == 0) + { + int i = cache_free_uri(cache, uri); + if (i == -1) return; + /* shift array */ + if (i != --cache->count) + memmove(&cache->uris[i], &cache->uris[i+1], (cache->count-i)*sizeof(xmlChar*)); + } +} + /* This one adds all namespaces defined in document to a cache, without anything associated with uri obviously. Unfortunately namespace:: axis implementation in libxml2 differs from what we need, @@ -1033,8 +1079,7 @@ HRESULT cache_from_doc_ns(IXMLDOMSchemaCollection2 *iface, xmlnode *node) entry->schema = NULL; entry->doc = NULL; - xmlHashRemoveEntry(This->cache, ns->href, cache_free); - xmlHashAddEntry(This->cache, ns->href, entry); + cache_add_entry(This, ns->href, entry); } pos++; } @@ -1091,6 +1136,11 @@ static ULONG WINAPI schema_cache_Release(IXMLDOMSchemaCollection2* iface) if (ref == 0) { + int i; + + for (i = 0; i < This->count; i++) + heap_free(This->uris[i]); + heap_free(This->uris); xmlHashFree(This->cache, cache_free); release_dispex(&This->dispex); heap_free(This); @@ -1146,7 +1196,7 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri { case VT_NULL: { - xmlHashRemoveEntry(This->cache, name, cache_free); + cache_remove_entry(This, name); } break; @@ -1164,8 +1214,7 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri return E_FAIL; } - xmlHashRemoveEntry(This->cache, name, cache_free); - xmlHashAddEntry(This->cache, name, entry); + cache_add_entry(This, name, entry); } break; @@ -1214,8 +1263,7 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri return E_FAIL; } - xmlHashRemoveEntry(This->cache, name, cache_free); - xmlHashAddEntry(This->cache, name, entry); + cache_add_entry(This, name, entry); } break; @@ -1263,7 +1311,7 @@ static HRESULT WINAPI schema_cache_remove(IXMLDOMSchemaCollection2* iface, BSTR if (This->version == MSXML6) return E_NOTIMPL; - xmlHashRemoveEntry(This->cache, name, cache_free); + cache_remove_entry(This, name); heap_free(name); return S_OK; } @@ -1275,33 +1323,25 @@ static HRESULT WINAPI schema_cache_get_length(IXMLDOMSchemaCollection2* iface, L if (!length) return E_POINTER; - *length = xmlHashSize(This->cache); + + *length = This->count; return S_OK; } -static void cache_index(void* data /* ignored */, void* index, xmlChar* name) -{ - cache_index_data* index_data = (cache_index_data*)index; - - if (index_data->index-- == 0) - *index_data->out = bstr_from_xmlChar(name); -} - static HRESULT WINAPI schema_cache_get_namespaceURI(IXMLDOMSchemaCollection2* iface, - LONG index, BSTR* len) + LONG index, BSTR* uri) { schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - cache_index_data data = {index, len}; - TRACE("(%p)->(%i %p)\n", This, index, len); - if (!len) + TRACE("(%p)->(%i %p)\n", This, index, uri); + + if (!uri) return E_POINTER; - if (index >= xmlHashSize(This->cache)) + if (index >= This->count) return E_FAIL; - *len = NULL; - xmlHashScan(This->cache, cache_index, &data); + *uri = bstr_from_xmlChar(This->uris[index]); return S_OK; } @@ -1313,7 +1353,7 @@ static void cache_copy(void* data, void* dest, xmlChar* name) if (xmlHashLookup(This->cache, name) == NULL) { cache_entry_add_ref(entry); - xmlHashAddEntry(This->cache, name, entry); + cache_add_entry(This, name, entry); } } @@ -1531,6 +1571,9 @@ HRESULT SchemaCache_create(MSXML_VERSION version, IUnknown* outer, void** obj) This->IXMLDOMSchemaCollection2_iface.lpVtbl = &XMLDOMSchemaCollection2Vtbl; This->cache = xmlHashCreate(DEFAULT_HASHTABLE_SIZE); + This->allocated = 10; + This->count = 0; + This->uris = heap_alloc(This->allocated*sizeof(xmlChar*)); This->ref = 1; This->version = version; This->validateOnLoad = VARIANT_TRUE; diff --git a/reactos/dll/win32/msxml3/text.c b/reactos/dll/win32/msxml3/text.c index dd761342ed6..efc79e547e1 100644 --- a/reactos/dll/win32/msxml3/text.c +++ b/reactos/dll/win32/msxml3/text.c @@ -29,6 +29,7 @@ //#include #ifdef HAVE_LIBXML2 # include +# include //# include #endif @@ -58,6 +59,11 @@ static inline domtext *impl_from_IXMLDOMText( IXMLDOMText *iface ) return CONTAINING_RECORD(iface, domtext, IXMLDOMText_iface); } +static void domtext_reset_noenc(domtext *This) +{ + This->node.node->name = NULL; +} + static HRESULT WINAPI domtext_QueryInterface( IXMLDOMText *iface, REFIID riid, @@ -185,6 +191,7 @@ static HRESULT WINAPI domtext_put_nodeValue( TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); + domtext_reset_noenc(This); return node_put_value(&This->node, &value); } @@ -374,6 +381,7 @@ static HRESULT WINAPI domtext_put_text( { domtext *This = impl_from_IXMLDOMText( iface ); TRACE("(%p)->(%s)\n", This, debugstr_w(p)); + domtext_reset_noenc(This); return node_put_text( &This->node, p ); } @@ -611,7 +619,14 @@ static HRESULT WINAPI domtext_put_data( BSTR data) { domtext *This = impl_from_IXMLDOMText( iface ); + static WCHAR rnW[] = {'\r','\n',0}; + TRACE("(%p)->(%s)\n", This, debugstr_w(data)); + + if (data && !strcmpW(rnW, data)) + This->node.node->name = xmlStringTextNoenc; + else + domtext_reset_noenc(This); return node_set_content(&This->node, data); } diff --git a/reactos/dll/win32/msxml3/xmlparser.c b/reactos/dll/win32/msxml3/xmlparser.c index 9a500e58c27..7807ea1b309 100644 --- a/reactos/dll/win32/msxml3/xmlparser.c +++ b/reactos/dll/win32/msxml3/xmlparser.c @@ -49,6 +49,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); typedef struct _xmlparser { IXMLParser IXMLParser_iface; + IXMLNodeFactory *nodefactory; + IUnknown *input; LONG ref; int flags; @@ -98,6 +100,12 @@ static ULONG WINAPI xmlparser_Release(IXMLParser* iface) TRACE("(%p)->(%d)\n", This, ref); if ( ref == 0 ) { + if(This->input) + IUnknown_Release(This->input); + + if(This->nodefactory) + IXMLNodeFactory_Release(This->nodefactory); + heap_free( This ); } @@ -109,18 +117,33 @@ static HRESULT WINAPI xmlparser_SetFactory(IXMLParser *iface, IXMLNodeFactory *p { xmlparser *This = impl_from_IXMLParser( iface ); - FIXME("(%p %p)\n", This, pNodeFactory); + TRACE("(%p %p)\n", This, pNodeFactory); - return E_NOTIMPL; + if(This->nodefactory) + IXMLNodeFactory_Release(This->nodefactory); + + This->nodefactory = pNodeFactory; + if(This->nodefactory) + IXMLNodeFactory_AddRef(This->nodefactory); + + return S_OK; } static HRESULT WINAPI xmlparser_GetFactory(IXMLParser *iface, IXMLNodeFactory **ppNodeFactory) { xmlparser *This = impl_from_IXMLParser( iface ); - FIXME("(%p, %p)\n", This, ppNodeFactory); + TRACE("(%p, %p)\n", This, ppNodeFactory); - return E_NOTIMPL; + if(!ppNodeFactory) + return E_INVALIDARG; + + *ppNodeFactory = This->nodefactory; + + if(*ppNodeFactory) + IXMLNodeFactory_AddRef(*ppNodeFactory); + + return S_OK; } static HRESULT WINAPI xmlparser_Abort(IXMLParser *iface, BSTR bstrErrorInfo) @@ -230,9 +253,18 @@ static HRESULT WINAPI xmlparser_SetInput(IXMLParser *iface, IUnknown *pStm) { xmlparser *This = impl_from_IXMLParser( iface ); - FIXME("(%p %p)\n", This, pStm); + TRACE("(%p %p)\n", This, pStm); - return E_NOTIMPL; + if(!pStm) + return E_INVALIDARG; + + if(This->input) + IUnknown_Release(This->input); + + This->input = pStm; + IUnknown_AddRef(This->input); + + return S_OK; } static HRESULT WINAPI xmlparser_PushData(IXMLParser *iface, const char *pData, @@ -418,6 +450,8 @@ HRESULT XMLParser_create(IUnknown* pUnkOuter, void**ppObj) return E_OUTOFMEMORY; This->IXMLParser_iface.lpVtbl = &xmlparser_vtbl; + This->nodefactory = NULL; + This->input = NULL; This->flags = 0; This->ref = 1; diff --git a/reactos/dll/win32/msxml3/xslpattern.l b/reactos/dll/win32/msxml3/xslpattern.l index eb84e40bc79..bda383602cf 100644 --- a/reactos/dll/win32/msxml3/xslpattern.l +++ b/reactos/dll/win32/msxml3/xslpattern.l @@ -58,7 +58,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); %option reentrant bison-bridge %option noyywrap %option prefix="xslpattern_" -%option noinput nounput +%option noinput nounput never-interactive /* From the w3c XML standard * */ diff --git a/reactos/dll/win32/msxml3/xslpattern.yy.c b/reactos/dll/win32/msxml3/xslpattern.yy.c index 489a47474e5..f61ced65b8a 100644 --- a/reactos/dll/win32/msxml3/xslpattern.yy.c +++ b/reactos/dll/win32/msxml3/xslpattern.yy.c @@ -872,16 +872,12 @@ yy_match: yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 138 ); + while ( yy_current_state != 95 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; yy_find_action: yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } YY_DO_BEFORE_ACTION; @@ -1088,7 +1084,7 @@ YY_RULE_SETUP #line 153 "xslpattern.l" ECHO; YY_BREAK -#line 1092 "xslpattern.yy.c" +#line 1088 "xslpattern.yy.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1155,7 +1151,8 @@ case YY_STATE_EOF(INITIAL): else { - yy_cp = yyg->yy_c_buf_p; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; } } @@ -1609,10 +1606,6 @@ static void xslpattern__load_buffer_state (yyscan_t yyscanner) xslpattern_free((void *) b ,yyscanner ); } -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a xslpattern_restart() or at EOF. @@ -1637,7 +1630,7 @@ extern int isatty (int ); b->yy_bs_column = 0; } - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = 0; errno = oerrno; } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 88d684edc6f..f2f3e7aad9b 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -120,7 +120,7 @@ reactos/dll/win32/msvfw32 # Autosync reactos/dll/win32/msvidc32 # Autosync reactos/dll/win32/msxml # Synced to Wine-1.5.19 reactos/dll/win32/msxml2 # Synced to Wine-1.5.19 -reactos/dll/win32/msxml3 # Synced to Wine-1.5.12 +reactos/dll/win32/msxml3 # Synced to Wine-1.5.26 reactos/dll/win32/msxml4 # Synced to Wine-1.5.19 reactos/dll/win32/msxml6 # Synced to Wine-1.5.19 reactos/dll/win32/nddeapi # Synced to Wine-1.5.19