* Sync with Wine 1.7.1.
CORE-7469

svn path=/trunk/; revision=60339
This commit is contained in:
Amine Khaldi 2013-09-23 11:38:27 +00:00
parent 82d7133b7d
commit eb591dfbc1
18 changed files with 440 additions and 90 deletions

View file

@ -1,7 +1,4 @@
remove_definitions(-D_WIN32_WINNT=0x502)
add_definitions(-D_WIN32_WINNT=0x601)
add_definitions(
-D__WINESRC__
-D_WINE
@ -13,9 +10,7 @@ if(MSVC)
endif()
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
spec2def(msxml3.dll msxml3.spec ADD_IMPORTLIB)
add_typelib(msxml3_v1.idl)
list(APPEND SOURCE
@ -56,24 +51,17 @@ list(APPEND SOURCE
${CMAKE_CURRENT_BINARY_DIR}/msxml3_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/msxml3.def)
list(APPEND msxml3_rc_deps
${CMAKE_CURRENT_SOURCE_DIR}/msxml3.manifest
${CMAKE_CURRENT_SOURCE_DIR}/msxml3_v1.rgs
${CMAKE_CURRENT_SOURCE_DIR}/xmlparser.rgs
${CMAKE_CURRENT_BINARY_DIR}/msxml3_v1.tlb)
set_source_files_properties(version.rc PROPERTIES OBJECT_DEPENDS "${msxml3_rc_deps}")
add_library(msxml3 SHARED ${SOURCE} version.rc)
if(NOT MSVC)
# FIXME: http://www.cmake.org/Bug/view.php?id=12998
#allow_warnings(msxml3)
set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-Wno-error")
endif()
add_idl_headers(xmlparser_idlheader xmlparser.idl)
add_dependencies(msxml3 xmlparser_idlheader)
set_module_type(msxml3 win32dll)
set_source_files_properties(version.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/msxml3_v1.tlb)
target_link_libraries(msxml3 libxml2 uuid wine wineldr)
add_importlibs(msxml3 urlmon wininet ws2_32 comctl32 shell32 shlwapi cabinet oleaut32 ole32 version user32 gdi32 advapi32 msvcrt kernel32 ntdll)
# msxml3_v1.tlb needs stdole2.tlb
add_dependencies(msxml3 stdole2)
target_link_libraries(msxml3 libxml2 uuid wine)
add_importlibs(msxml3 urlmon ws2_32 shlwapi oleaut32 ole32 user32 msvcrt kernel32 ntdll)
add_dependencies(msxml3 xmlparser_idlheader stdole2) # msxml3_v1.tlb needs stdole2.tlb
add_cd_file(TARGET msxml3 DESTINATION reactos/system32 FOR all)

View file

@ -46,6 +46,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
#ifdef HAVE_LIBXML2
static const xmlChar xmlns[] = "xmlns";
typedef struct _domattr
{
xmlnode node;
@ -56,7 +58,7 @@ typedef struct _domattr
static const tid_t domattr_se_tids[] = {
IXMLDOMNode_tid,
IXMLDOMAttribute_tid,
0
NULL_tid
};
static inline domattr *impl_from_IXMLDOMAttribute( IXMLDOMAttribute *iface )
@ -545,8 +547,29 @@ static HRESULT WINAPI domattr_get_namespaceURI(
BSTR* p)
{
domattr *This = impl_from_IXMLDOMAttribute( iface );
xmlNsPtr ns = This->node.node->ns;
TRACE("(%p)->(%p)\n", This, p);
return node_get_namespaceURI(&This->node, p);
if (!p)
return E_INVALIDARG;
*p = NULL;
if (ns)
{
/* special case for default namespace definition */
if (xmlStrEqual(This->node.node->name, xmlns))
*p = bstr_from_xmlChar(xmlns);
else if (xmlStrEqual(ns->prefix, xmlns))
*p = SysAllocStringLen(NULL, 0);
else if (ns->href)
*p = bstr_from_xmlChar(ns->href);
}
TRACE("uri: %s\n", debugstr_w(*p));
return *p ? S_OK : S_FALSE;
}
static HRESULT WINAPI domattr_get_prefix(
@ -554,8 +577,26 @@ static HRESULT WINAPI domattr_get_prefix(
BSTR* prefix)
{
domattr *This = impl_from_IXMLDOMAttribute( iface );
xmlNsPtr ns = This->node.node->ns;
TRACE("(%p)->(%p)\n", This, prefix);
return node_get_prefix( &This->node, prefix );
if (!prefix) return E_INVALIDARG;
*prefix = NULL;
if (ns)
{
/* special case for default namespace definition */
if (xmlStrEqual(This->node.node->name, xmlns))
*prefix = bstr_from_xmlChar(xmlns);
else if (ns->prefix)
*prefix = bstr_from_xmlChar(ns->prefix);
}
TRACE("prefix: %s\n", debugstr_w(*prefix));
return *prefix ? S_OK : S_FALSE;
}
static HRESULT WINAPI domattr_get_baseName(

View file

@ -55,7 +55,7 @@ typedef struct
static const tid_t domcdata_se_tids[] = {
IXMLDOMNode_tid,
IXMLDOMCDATASection_tid,
0
NULL_tid
};
static inline domcdata *impl_from_IXMLDOMCDATASection( IXMLDOMCDATASection *iface )
@ -336,7 +336,7 @@ static HRESULT WINAPI domcdata_hasChildNodes(
{
domcdata *This = impl_from_IXMLDOMCDATASection( iface );
TRACE("(%p)->(%p)\n", This, ret);
return node_has_childnodes(&This->node, ret);
return return_var_false(ret);
}
static HRESULT WINAPI domcdata_get_ownerDocument(

View file

@ -55,7 +55,7 @@ typedef struct _domcomment
static const tid_t domcomment_se_tids[] = {
IXMLDOMNode_tid,
IXMLDOMComment_tid,
0
NULL_tid
};
static inline domcomment *impl_from_IXMLDOMComment( IXMLDOMComment *iface )
@ -335,7 +335,7 @@ static HRESULT WINAPI domcomment_hasChildNodes(
{
domcomment *This = impl_from_IXMLDOMComment( iface );
TRACE("(%p)->(%p)\n", This, ret);
return node_has_childnodes(&This->node, ret);
return return_var_false(ret);
}
static HRESULT WINAPI domcomment_get_ownerDocument(

View file

@ -55,7 +55,7 @@ typedef struct _domfrag
static const tid_t domfrag_se_tids[] = {
IXMLDOMNode_tid,
IXMLDOMDocumentFragment_tid,
0
NULL_tid
};
static inline domfrag *impl_from_IXMLDOMDocumentFragment( IXMLDOMDocumentFragment *iface )

View file

@ -419,10 +419,26 @@ static void sax_characters(void *ctx, const xmlChar *ch, int len)
if (ctxt->node)
{
/* during domdoc_loadXML() the xmlDocPtr->_private data is not available */
xmlChar cur = *(ctxt->input->cur);
/* Characters are reported with multiple calls, for example each charref is reported with a separate
call and then parser appends it to a single text node or creates a new node if not created.
It's not possible to tell if it's ignorable data or not just looking at data itself cause it could be
space chars that separate charrefs or similar case. We only need to skip leading and trailing spaces,
or whole node if it has nothing but space chars, so to detect leading space node->last is checked that
contains text node pointer if already created, trailing spaces are detected directly looking at parser input
for next '<' opening bracket - similar logic is used by libxml2 itself. Basically 'cur' == '<' means the last
chunk of char data, in case it's not the last chunk we check for previously added node type and if it's not
a text node it's safe to ignore.
Note that during domdoc_loadXML() the xmlDocPtr->_private data is not available. */
if (!This->properties->preserving &&
!is_preserving_whitespace(ctxt->node) &&
strn_isspace(ch, len))
strn_isspace(ch, len) &&
(!ctxt->node->last ||
((ctxt->node->last && (cur == '<' || ctxt->node->last->type != XML_TEXT_NODE))
)))
return;
}
@ -852,7 +868,7 @@ static const tid_t domdoc_se_tids[] = {
IXMLDOMDocument_tid,
IXMLDOMDocument2_tid,
IXMLDOMDocument3_tid,
0
NULL_tid
};
static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID riid, void** ppvObject )
@ -1921,9 +1937,6 @@ static HRESULT WINAPI domdoc_createNode(
hr = get_node_type(Type, &node_type);
if(FAILED(hr)) return hr;
if(namespaceURI && namespaceURI[0] && node_type != NODE_ELEMENT)
FIXME("nodes with namespaces currently not supported.\n");
TRACE("node_type %d\n", node_type);
/* exit earlier for types that need name */
@ -1966,8 +1979,26 @@ static HRESULT WINAPI domdoc_createNode(
break;
}
case NODE_ATTRIBUTE:
xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
{
xmlChar *local, *prefix;
local = xmlSplitQName2(xml_name, &prefix);
xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), local ? local : xml_name, NULL);
if (local || (href && *href))
{
/* we need a floating namespace here, it can't be created linked to attribute from
a start */
xmlNsPtr ns = xmlNewNs(NULL, href, prefix);
xmlSetNs(xmlnode, ns);
}
xmlFree(local);
xmlFree(prefix);
break;
}
case NODE_TEXT:
xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
break;
@ -2984,7 +3015,7 @@ static HRESULT WINAPI domdoc_setProperty(
lstrcmpiW(p, PropertyResolveExternalsW) == 0)
{
/* Ignore */
FIXME("Ignoring property %s, value %d\n", debugstr_w(p), V_BOOL(&value));
FIXME("Ignoring property %s, value %s\n", debugstr_w(p), debugstr_variant(&value));
return S_OK;
}

View file

@ -61,7 +61,7 @@ static const struct nodemap_funcs domelem_attr_map;
static const tid_t domelem_se_tids[] = {
IXMLDOMNode_tid,
IXMLDOMElement_tid,
0
NULL_tid
};
static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )

View file

@ -55,7 +55,7 @@ typedef struct _entityref
static const tid_t domentityref_se_tids[] = {
IXMLDOMNode_tid,
IXMLDOMEntityReference_tid,
0
NULL_tid
};
static inline entityref *impl_from_IXMLDOMEntityReference( IXMLDOMEntityReference *iface )

View file

@ -622,8 +622,27 @@ static HRESULT WINAPI Authenticate_Authenticate(IAuthenticate *iface,
HWND *hwnd, LPWSTR *username, LPWSTR *password)
{
BindStatusCallback *This = impl_from_IAuthenticate(iface);
FIXME("(%p)->(%p %p %p)\n", This, hwnd, username, password);
return E_NOTIMPL;
httprequest *request = This->request;
TRACE("(%p)->(%p %p %p)\n", This, hwnd, username, password);
if (request->user && *request->user)
{
if (hwnd) *hwnd = NULL;
*username = CoTaskMemAlloc(SysStringByteLen(request->user)+sizeof(WCHAR));
*password = CoTaskMemAlloc(SysStringByteLen(request->password)+sizeof(WCHAR));
if (!*username || !*password)
{
CoTaskMemFree(*username);
CoTaskMemFree(*password);
return E_OUTOFMEMORY;
}
memcpy(*username, request->user, SysStringByteLen(request->user)+sizeof(WCHAR));
memcpy(*password, request->password, SysStringByteLen(request->password)+sizeof(WCHAR));
}
return S_OK;
}
static const IAuthenticateVtbl AuthenticateVtbl = {
@ -706,7 +725,7 @@ static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback *
heap_free(bsc);
return hr;
}
if ((hr = SafeArrayGetUBound(sa, 1, &size) != S_OK))
if ((hr = SafeArrayGetUBound(sa, 1, &size)) != S_OK)
{
SafeArrayUnaccessData(sa);
heap_free(bsc);
@ -720,27 +739,31 @@ static HRESULT BindStatusCallback_create(httprequest* This, BindStatusCallback *
/* fall through */
case VT_EMPTY:
case VT_ERROR:
case VT_NULL:
ptr = NULL;
size = 0;
break;
}
bsc->body = GlobalAlloc(GMEM_FIXED, size);
if (!bsc->body)
if (size)
{
if (V_VT(body) == VT_BSTR)
heap_free(ptr);
else if (V_VT(body) == (VT_ARRAY|VT_UI1))
SafeArrayUnaccessData(sa);
bsc->body = GlobalAlloc(GMEM_FIXED, size);
if (!bsc->body)
{
if (V_VT(body) == VT_BSTR)
heap_free(ptr);
else if (V_VT(body) == (VT_ARRAY|VT_UI1))
SafeArrayUnaccessData(sa);
heap_free(bsc);
return E_OUTOFMEMORY;
heap_free(bsc);
return E_OUTOFMEMORY;
}
send_data = GlobalLock(bsc->body);
memcpy(send_data, ptr, size);
GlobalUnlock(bsc->body);
}
send_data = GlobalLock(bsc->body);
memcpy(send_data, ptr, size);
GlobalUnlock(bsc->body);
if (V_VT(body) == VT_BSTR)
heap_free(ptr);
else if (V_VT(body) == (VT_ARRAY|VT_UI1))
@ -885,12 +908,6 @@ static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url,
return hr;
}
This->uri = uri;
VariantInit(&is_async);
hr = VariantChangeType(&is_async, &async, 0, VT_BOOL);
This->async = hr == S_OK && V_BOOL(&is_async);
VariantInit(&str);
hr = VariantChangeType(&str, &user, 0, VT_BSTR);
if (hr == S_OK)
@ -901,6 +918,38 @@ static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url,
if (hr == S_OK)
This->password = V_BSTR(&str);
/* add authentication info */
if (This->user && *This->user)
{
IUriBuilder *builder;
hr = CreateIUriBuilder(uri, 0, 0, &builder);
if (hr == S_OK)
{
IUri *full_uri;
IUriBuilder_SetUserName(builder, This->user);
IUriBuilder_SetPassword(builder, This->password);
hr = IUriBuilder_CreateUri(builder, -1, 0, 0, &full_uri);
if (hr == S_OK)
{
IUri_Release(uri);
uri = full_uri;
}
else
WARN("failed to create modified uri, 0x%08x\n", hr);
IUriBuilder_Release(builder);
}
else
WARN("IUriBuilder creation failed, 0x%08x\n", hr);
}
This->uri = uri;
VariantInit(&is_async);
hr = VariantChangeType(&is_async, &async, 0, VT_BOOL);
This->async = hr == S_OK && V_BOOL(&is_async);
httprequest_setreadystate(This, READYSTATE_LOADING);
return S_OK;

View file

@ -212,7 +212,7 @@ static void init_libxslt(void)
#endif
}
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID reserved)
{
MSXML_hInstance = hInstDLL;
@ -243,7 +243,6 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
{
pxsltCleanupGlobals();
wine_dlclose(libxslt_handle, NULL, 0);
libxslt_handle = NULL;
}
#endif
#ifdef HAVE_LIBXML2

View file

@ -475,6 +475,15 @@ static inline HRESULT return_null_bstr(BSTR *p)
return S_FALSE;
}
static inline HRESULT return_var_false(VARIANT_BOOL *p)
{
if(!p)
return E_INVALIDARG;
*p = VARIANT_FALSE;
return S_FALSE;
}
extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText,
LONG line, LONG linepos, LONG filepos ) DECLSPEC_HIDDEN;
extern HRESULT DOMDocument_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN;

View file

@ -1,7 +1,7 @@
/*
* MXWriter implementation
*
* Copyright 2011-2012 Nikolay Sivov for CodeWeavers
* Copyright 2011-2013 Nikolay Sivov for CodeWeavers
* Copyright 2011 Thomas Mullaly
*
* This library is free software; you can redistribute it and/or
@ -46,6 +46,8 @@ static const WCHAR emptyW[] = {0};
static const WCHAR spaceW[] = {' '};
static const WCHAR quotW[] = {'\"'};
static const WCHAR closetagW[] = {'>','\r','\n'};
static const WCHAR crlfW[] = {'\r','\n'};
static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '};
/* should be ordered as encoding names are sorted */
typedef enum
@ -149,6 +151,10 @@ typedef struct
BOOL prop_changed;
BOOL cdata;
BOOL text; /* last node was text node, so we shouldn't indent next node */
BOOL newline; /* newline was already added as a part of previous call */
UINT indent; /* indentation level for next node */
BSTR version;
BSTR encoding; /* exact property value */
@ -457,14 +463,13 @@ static WCHAR *get_escaped_string(const WCHAR *str, escape_mode mode, int *len)
return ret;
}
static void write_prolog_buffer(const mxwriter *This)
static void write_prolog_buffer(mxwriter *This)
{
static const WCHAR versionW[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','='};
static const WCHAR encodingW[] = {' ','e','n','c','o','d','i','n','g','=','\"'};
static const WCHAR standaloneW[] = {' ','s','t','a','n','d','a','l','o','n','e','=','\"'};
static const WCHAR yesW[] = {'y','e','s','\"','?','>'};
static const WCHAR noW[] = {'n','o','\"','?','>'};
static const WCHAR crlfW[] = {'\r','\n'};
/* version */
write_output_buffer(This->buffer, versionW, sizeof(versionW)/sizeof(WCHAR));
@ -486,6 +491,7 @@ static void write_prolog_buffer(const mxwriter *This)
write_output_buffer(This->buffer, noW, sizeof(noW)/sizeof(WCHAR));
write_output_buffer(This->buffer, crlfW, sizeof(crlfW)/sizeof(WCHAR));
This->newline = TRUE;
}
/* Attempts to the write data from the mxwriter's buffer to
@ -539,6 +545,41 @@ static void close_element_starttag(const mxwriter *This)
write_output_buffer(This->buffer, gtW, 1);
}
static void write_node_indent(mxwriter *This)
{
static const WCHAR tabW[] = {'\t'};
int indent = This->indent;
if (!This->props[MXWriter_Indent] || This->text)
{
This->text = FALSE;
return;
}
/* This is to workaround PI output logic that always puts newline chars,
document prolog PI does that too. */
if (!This->newline)
write_output_buffer(This->buffer, crlfW, sizeof(crlfW)/sizeof(WCHAR));
while (indent--)
write_output_buffer(This->buffer, tabW, 1);
This->newline = FALSE;
This->text = FALSE;
}
static inline void writer_inc_indent(mxwriter *This)
{
This->indent++;
}
static inline void writer_dec_indent(mxwriter *This)
{
if (This->indent) This->indent--;
/* depth is decreased only when element is closed, meaning it's not a text node
at this point */
This->text = FALSE;
}
static void set_element_name(mxwriter *This, const WCHAR *name, int len)
{
SysFreeString(This->element);
@ -1085,8 +1126,11 @@ static HRESULT WINAPI SAXContentHandler_startElement(
set_element_name(This, QName ? QName : emptyW,
QName ? nQName : 0);
write_node_indent(This);
write_output_buffer(This->buffer, ltW, 1);
write_output_buffer(This->buffer, QName, nQName);
writer_inc_indent(This);
if (attr)
{
@ -1150,6 +1194,8 @@ static HRESULT WINAPI SAXContentHandler_endElement(
(nQName == -1 && This->class_version == MSXML6))
return E_INVALIDARG;
writer_dec_indent(This);
if (This->element)
{
static const WCHAR closeW[] = {'/','>'};
@ -1160,6 +1206,7 @@ static HRESULT WINAPI SAXContentHandler_endElement(
static const WCHAR closetagW[] = {'<','/'};
static const WCHAR gtW[] = {'>'};
write_node_indent(This);
write_output_buffer(This->buffer, closetagW, 2);
write_output_buffer(This->buffer, QName, nQName);
write_output_buffer(This->buffer, gtW, 1);
@ -1184,6 +1231,9 @@ static HRESULT WINAPI SAXContentHandler_characters(
close_element_starttag(This);
set_element_name(This, NULL, 0);
if (!This->cdata)
This->text = TRUE;
if (nchars)
{
if (This->cdata || This->props[MXWriter_DisableEscaping] == VARIANT_TRUE)
@ -1233,6 +1283,7 @@ static HRESULT WINAPI SAXContentHandler_processingInstruction(
if (!target) return E_INVALIDARG;
write_node_indent(This);
write_output_buffer(This->buffer, openpiW, sizeof(openpiW)/sizeof(WCHAR));
if (*target)
@ -1245,6 +1296,7 @@ static HRESULT WINAPI SAXContentHandler_processingInstruction(
}
write_output_buffer(This->buffer, closepiW, sizeof(closepiW)/sizeof(WCHAR));
This->newline = TRUE;
return S_OK;
}
@ -1384,6 +1436,7 @@ static HRESULT WINAPI SAXLexicalHandler_startCDATA(ISAXLexicalHandler *iface)
TRACE("(%p)\n", This);
write_node_indent(This);
write_output_buffer(This->buffer, scdataW, sizeof(scdataW)/sizeof(WCHAR));
This->cdata = TRUE;
@ -1414,6 +1467,7 @@ static HRESULT WINAPI SAXLexicalHandler_comment(ISAXLexicalHandler *iface, const
if (!chars) return E_INVALIDARG;
close_element_starttag(This);
write_node_indent(This);
write_output_buffer(This->buffer, copenW, sizeof(copenW)/sizeof(WCHAR));
if (nchars)
@ -1526,7 +1580,6 @@ static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface,
const WCHAR *name, int n_name, const WCHAR *value, int n_value)
{
mxwriter *This = impl_from_ISAXDeclHandler( iface );
static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '};
TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
debugstr_wn(value, n_value), n_value);
@ -1551,10 +1604,39 @@ static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface,
const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId,
const WCHAR *systemId, int n_systemId)
{
static const WCHAR publicW[] = {'P','U','B','L','I','C',' '};
static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '};
mxwriter *This = impl_from_ISAXDeclHandler( iface );
FIXME("(%p)->(%s:%d %s:%d %s:%d): stub\n", This, debugstr_wn(name, n_name), n_name,
TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name,
debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId);
return E_NOTIMPL;
if (!name) return E_INVALIDARG;
if (publicId && !systemId) return E_INVALIDARG;
if (!publicId && !systemId) return E_INVALIDARG;
write_output_buffer(This->buffer, entityW, sizeof(entityW)/sizeof(WCHAR));
if (n_name) {
write_output_buffer(This->buffer, name, n_name);
write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
}
if (publicId)
{
write_output_buffer(This->buffer, publicW, sizeof(publicW)/sizeof(WCHAR));
write_output_buffer_quoted(This->buffer, publicId, n_publicId);
write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR));
write_output_buffer_quoted(This->buffer, systemId, n_systemId);
}
else
{
write_output_buffer(This->buffer, systemW, sizeof(systemW)/sizeof(WCHAR));
write_output_buffer_quoted(This->buffer, systemId, n_systemId);
}
write_output_buffer(This->buffer, closetagW, sizeof(closetagW)/sizeof(WCHAR));
return S_OK;
}
static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = {
@ -1612,6 +1694,9 @@ HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *outer, void **ppObj)
This->element = NULL;
This->cdata = FALSE;
This->indent = 0;
This->text = FALSE;
This->newline = FALSE;
This->dest = NULL;
This->dest_written = 0;
@ -1806,11 +1891,32 @@ static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
return S_OK;
}
static mxattribute *get_attribute_byindex(mxattributes *attrs, int index)
{
if (index < 0 || index >= attrs->length) return NULL;
return &attrs->attr[index];
}
static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
{
mxattributes *This = impl_from_IMXAttributes( iface );
FIXME("(%p)->(%d): stub\n", This, index);
return E_NOTIMPL;
mxattribute *dst;
TRACE("(%p)->(%d)\n", This, index);
if (!(dst = get_attribute_byindex(This, index))) return E_INVALIDARG;
/* no need to remove last attribute, just make it inaccessible */
if (index + 1 == This->length)
{
This->length--;
return S_OK;
}
memmove(dst, dst + 1, (This->length-index-1)*sizeof(*dst));
This->length--;
return S_OK;
}
static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
@ -1833,29 +1939,61 @@ static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
BSTR localName)
{
mxattributes *This = impl_from_IMXAttributes( iface );
FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(localName));
return E_NOTIMPL;
mxattribute *attr;
TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(localName));
if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
SysFreeString(attr->local);
attr->local = SysAllocString(localName);
return S_OK;
}
static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
{
mxattributes *This = impl_from_IMXAttributes( iface );
FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(QName));
return E_NOTIMPL;
mxattribute *attr;
TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(QName));
if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
SysFreeString(attr->qname);
attr->qname = SysAllocString(QName);
return S_OK;
}
static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
{
mxattributes *This = impl_from_IMXAttributes( iface );
FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(uri));
return E_NOTIMPL;
mxattribute *attr;
TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(uri));
if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
SysFreeString(attr->uri);
attr->uri = SysAllocString(uri);
return S_OK;
}
static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
{
mxattributes *This = impl_from_IMXAttributes( iface );
FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(value));
return E_NOTIMPL;
mxattribute *attr;
TRACE("(%p)->(%d %s)\n", This, index, debugstr_w(value));
if (!(attr = get_attribute_byindex(This, index))) return E_INVALIDARG;
SysFreeString(attr->value);
attr->value = SysAllocString(value);
return S_OK;
}
static const IMXAttributesVtbl MXAttributesVtbl = {

View file

@ -153,7 +153,7 @@ static HRESULT WINAPI SupportErrorInfo_InterfaceSupportsErrorInfo(ISupportErrorI
TRACE("(%p)->(%s)\n", This, debugstr_guid(riid));
tid = This->iids;
while (*tid)
while (*tid != NULL_tid)
{
if (IsEqualGUID(riid, get_riid_from_tid(*tid)))
return S_OK;
@ -899,6 +899,50 @@ HRESULT node_get_xml(xmlnode *This, BOOL ensure_eol, BSTR *ret)
return *ret ? S_OK : E_OUTOFMEMORY;
}
/* duplicates xmlBufferWriteQuotedString() logic */
static void xml_write_quotedstring(xmlOutputBufferPtr buf, const xmlChar *string)
{
const xmlChar *cur, *base;
if (xmlStrchr(string, '\"'))
{
if (xmlStrchr(string, '\''))
{
xmlOutputBufferWrite(buf, 1, "\"");
base = cur = string;
while (*cur)
{
if (*cur == '"')
{
if (base != cur)
xmlOutputBufferWrite(buf, cur-base, (const char*)base);
xmlOutputBufferWrite(buf, 6, "&quot;");
cur++;
base = cur;
}
else
cur++;
}
if (base != cur)
xmlOutputBufferWrite(buf, cur-base, (const char*)base);
xmlOutputBufferWrite(buf, 1, "\"");
}
else
{
xmlOutputBufferWrite(buf, 1, "\'");
xmlOutputBufferWriteString(buf, (const char*)string);
xmlOutputBufferWrite(buf, 1, "\'");
}
}
else
{
xmlOutputBufferWrite(buf, 1, "\"");
xmlOutputBufferWriteString(buf, (const char*)string);
xmlOutputBufferWrite(buf, 1, "\"");
}
}
static void htmldtd_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc)
{
xmlDtdPtr cur = doc->intSubset;
@ -908,17 +952,17 @@ static void htmldtd_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc)
if (cur->ExternalID)
{
xmlOutputBufferWriteString(buf, " PUBLIC ");
xmlBufferWriteQuotedString(buf->buffer, cur->ExternalID);
xml_write_quotedstring(buf, cur->ExternalID);
if (cur->SystemID)
{
xmlOutputBufferWriteString(buf, " ");
xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
xml_write_quotedstring(buf, cur->SystemID);
}
}
else if (cur->SystemID)
{
xmlOutputBufferWriteString(buf, " SYSTEM ");
xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
xml_write_quotedstring(buf, cur->SystemID);
}
xmlOutputBufferWriteString(buf, ">\n");
}
@ -946,6 +990,15 @@ static void htmldoc_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc)
doc->type = type;
}
static const xmlChar *get_output_buffer_content(xmlOutputBufferPtr output)
{
#ifdef LIBXML2_NEW_BUFFER
return xmlOutputBufferGetContent(output);
#else
return xmlBufferContent(output->buffer);
#endif
}
HRESULT node_transform_node(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR *p)
{
#ifdef SONAME_LIBXSLT
@ -974,7 +1027,7 @@ HRESULT node_transform_node(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR *
if (output)
{
htmldoc_dumpcontent(output, result->doc);
content = xmlBufferContent(output->buffer);
content = get_output_buffer_content(output);
*p = bstr_from_xmlChar(content);
xmlOutputBufferClose(output);
}

View file

@ -57,7 +57,7 @@ static const struct nodemap_funcs dom_pi_attr_map;
static const tid_t dompi_se_tids[] = {
IXMLDOMNode_tid,
IXMLDOMProcessingInstruction_tid,
0
NULL_tid
};
static inline dom_pi *impl_from_IXMLDOMProcessingInstruction( IXMLDOMProcessingInstruction *iface )

View file

@ -1268,6 +1268,49 @@ static const struct ISAXAttributesVtbl isaxattributes_vtbl =
isaxattributes_getValueFromQName
};
/* Libxml2 escapes '&' back to char reference '&#38;' in attribute value,
so when document has escaped value with '&amp;' it's parsed to '&' and then
escaped to '&#38;'. This function takes care of ampersands only. */
static BSTR saxreader_get_unescaped_value(const xmlChar *buf, int len)
{
static const WCHAR ampescW[] = {'&','#','3','8',';',0};
WCHAR *dest, *ptrW, *str;
DWORD str_len;
BSTR bstr;
if (!buf)
return NULL;
str_len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
if (len != -1) str_len++;
str = heap_alloc(str_len*sizeof(WCHAR));
if (!str) return NULL;
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, str_len);
if (len != -1) str[str_len-1] = 0;
ptrW = str;
while ((dest = strstrW(ptrW, ampescW)))
{
WCHAR *src;
/* leave first '&' from a reference as a value */
src = dest + (sizeof(ampescW)/sizeof(WCHAR) - 1);
dest++;
/* move together with null terminator */
memmove(dest, src, (strlenW(src) + 1)*sizeof(WCHAR));
ptrW++;
}
bstr = SysAllocString(str);
heap_free(str);
return bstr;
}
static HRESULT SAXAttributes_populate(saxlocator *locator,
int nb_namespaces, const xmlChar **xmlNamespaces,
int nb_attributes, const xmlChar **xmlAttributes)
@ -1320,8 +1363,7 @@ static HRESULT SAXAttributes_populate(saxlocator *locator,
attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]);
attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]);
attrs[i].szValue = bstr_from_xmlCharN(xmlAttributes[i*5+3],
xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
attrs[i].szValue = saxreader_get_unescaped_value(xmlAttributes[i*5+3], xmlAttributes[i*5+4]-xmlAttributes[i*5+3]);
attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1],
xmlAttributes[i*5]);
}

View file

@ -333,7 +333,7 @@ static HRESULT WINAPI domtext_hasChildNodes(
{
domtext *This = impl_from_IXMLDOMText( iface );
TRACE("(%p)->(%p)\n", This, ret);
return node_has_childnodes(&This->node, ret);
return return_var_false(ret);
}
static HRESULT WINAPI domtext_get_ownerDocument(

View file

@ -22,7 +22,7 @@
#define WINE_PRODUCTVERSION_STR "8.90.1101.0"
#define WINE_EXTRAVALUES VALUE "OLESelfRegister",""
#include "wine/wine_common_ver.rc"
#include <wine/wine_common_ver.rc>
/* @makedep: msxml3.manifest */
WINE_MANIFEST 24 msxml3.manifest

View file

@ -132,7 +132,7 @@ reactos/dll/win32/msvfw32 # Synced to Wine-1.7.1
reactos/dll/win32/msvidc32 # Synced to Wine-1.7.1
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.26
reactos/dll/win32/msxml3 # Synced to Wine-1.7.1
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