mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
[MSXML3]
* Sync with Wine 1.7.1. CORE-7469 svn path=/trunk/; revision=60339
This commit is contained in:
parent
82d7133b7d
commit
eb591dfbc1
18 changed files with 440 additions and 90 deletions
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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, """);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -1268,6 +1268,49 @@ static const struct ISAXAttributesVtbl isaxattributes_vtbl =
|
|||
isaxattributes_getValueFromQName
|
||||
};
|
||||
|
||||
/* Libxml2 escapes '&' back to char reference '&' in attribute value,
|
||||
so when document has escaped value with '&' it's parsed to '&' and then
|
||||
escaped to '&'. 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]);
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue