diff --git a/reactos/dll/win32/msxml3/msxml_private.h b/reactos/dll/win32/msxml3/msxml_private.h index bc6926a1d94..447df8d94ef 100644 --- a/reactos/dll/win32/msxml3/msxml_private.h +++ b/reactos/dll/win32/msxml3/msxml_private.h @@ -164,24 +164,24 @@ const IID *get_riid_from_tid(enum tid_t tid) DECLSPEC_HIDDEN; /* memory allocation functions */ -static inline void *heap_alloc(size_t len) +static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t size) { - return HeapAlloc(GetProcessHeap(), 0, len); + return HeapAlloc(GetProcessHeap(), 0, size); } -static inline void *heap_alloc_zero(size_t len) +static inline void* __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t size) { - return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); } -static inline void *heap_realloc(void *mem, size_t len) +static inline void* __WINE_ALLOC_SIZE(2) heap_realloc(void *mem, size_t size) { - return HeapReAlloc(GetProcessHeap(), 0, mem, len); + return HeapReAlloc(GetProcessHeap(), 0, mem, size); } -static inline void *heap_realloc_zero(void *mem, size_t len) +static inline void* __WINE_ALLOC_SIZE(2) heap_realloc_zero(void *mem, size_t size) { - return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len); + return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, size); } static inline BOOL heap_free(void *mem) @@ -358,7 +358,8 @@ extern HRESULT node_get_text(const xmlnode*,BSTR*) DECLSPEC_HIDDEN; extern HRESULT node_select_nodes(const xmlnode*,BSTR,IXMLDOMNodeList**) DECLSPEC_HIDDEN; extern HRESULT node_select_singlenode(const xmlnode*,BSTR,IXMLDOMNode**) DECLSPEC_HIDDEN; extern HRESULT node_transform_node(const xmlnode*,IXMLDOMNode*,BSTR*) DECLSPEC_HIDDEN; -extern HRESULT node_transform_node_params(const xmlnode*,IXMLDOMNode*,BSTR*,IStream*,const struct xslprocessor_params*) DECLSPEC_HIDDEN; +extern HRESULT node_transform_node_params(const xmlnode*,IXMLDOMNode*,BSTR*,ISequentialStream*, + const struct xslprocessor_params*) DECLSPEC_HIDDEN; extern HRESULT node_create_supporterrorinfo(const tid_t*,void**) DECLSPEC_HIDDEN; extern HRESULT get_domdoc_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document) DECLSPEC_HIDDEN; diff --git a/reactos/dll/win32/msxml3/node.c b/reactos/dll/win32/msxml3/node.c index 4b83fe6521d..2e22d2ff685 100644 --- a/reactos/dll/win32/msxml3/node.c +++ b/reactos/dll/win32/msxml3/node.c @@ -1016,7 +1016,7 @@ static void xml_write_quotedstring(xmlOutputBufferPtr buf, const xmlChar *string static int XMLCALL transform_to_stream_write(void *context, const char *buffer, int len) { DWORD written; - HRESULT hr = IStream_Write((IStream*)context, buffer, len, &written); + HRESULT hr = ISequentialStream_Write((ISequentialStream *)context, buffer, len, &written); return hr == S_OK ? written : -1; } @@ -1261,7 +1261,7 @@ static HRESULT node_transform_write_to_bstr(xsltStylesheetPtr style, xmlDocPtr r return *str ? hr : E_OUTOFMEMORY; } -static HRESULT node_transform_write_to_stream(xsltStylesheetPtr style, xmlDocPtr result, IStream *stream) +static HRESULT node_transform_write_to_stream(xsltStylesheetPtr style, xmlDocPtr result, ISequentialStream *stream) { static const xmlChar *utf16 = (const xmlChar*)"UTF-16"; xmlOutputBufferPtr output; @@ -1297,7 +1297,7 @@ static HRESULT node_transform_write_to_stream(xsltStylesheetPtr style, xmlDocPtr #endif HRESULT node_transform_node_params(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR *p, - IStream *stream, const struct xslprocessor_params *params) + ISequentialStream *stream, const struct xslprocessor_params *params) { #ifdef SONAME_LIBXSLT xsltStylesheetPtr xsltSS; diff --git a/reactos/dll/win32/msxml3/saxreader.c b/reactos/dll/win32/msxml3/saxreader.c index 90d8c2186ba..a68a7725d27 100644 --- a/reactos/dll/win32/msxml3/saxreader.c +++ b/reactos/dll/win32/msxml3/saxreader.c @@ -2639,10 +2639,12 @@ static HRESULT internal_parse( } case VT_UNKNOWN: case VT_DISPATCH: { - IPersistStream *persistStream; ISequentialStream *stream = NULL; IXMLDOMDocument *xmlDoc; + if (!V_UNKNOWN(&varInput)) + return E_INVALIDARG; + if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK) { @@ -2656,34 +2658,11 @@ static HRESULT internal_parse( break; } - if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), - &IID_IPersistStream, (void**)&persistStream) == S_OK) - { - IStream *stream_copy; - - hr = CreateStreamOnHGlobal(NULL, TRUE, &stream_copy); - if(hr != S_OK) - { - IPersistStream_Release(persistStream); - return hr; - } - - hr = IPersistStream_Save(persistStream, stream_copy, TRUE); - IPersistStream_Release(persistStream); - if(hr == S_OK) - IStream_QueryInterface(stream_copy, &IID_ISequentialStream, (void**)&stream); - - IStream_Release(stream_copy); - } - /* try base interface first */ - if(!stream) - { - IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream); - if (!stream) - /* this should never happen if IStream is implemented properly, but just in case */ - IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream); - } + IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream); + if (!stream) + /* this should never happen if IStream is implemented properly, but just in case */ + IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream); if(stream) { diff --git a/reactos/dll/win32/msxml3/stylesheet.c b/reactos/dll/win32/msxml3/stylesheet.c index 2417968fee8..eb6358f6ce1 100644 --- a/reactos/dll/win32/msxml3/stylesheet.c +++ b/reactos/dll/win32/msxml3/stylesheet.c @@ -20,6 +20,9 @@ #include "precomp.h" +#include +#include + typedef struct { DispatchEx dispex; @@ -29,6 +32,14 @@ typedef struct IXMLDOMNode *node; } xsltemplate; +enum output_type +{ + PROCESSOR_OUTPUT_NOT_SET, + PROCESSOR_OUTPUT_STREAM, /* IStream or ISequentialStream */ + PROCESSOR_OUTPUT_PERSISTSTREAM, /* IPersistStream or IPersistStreamInit */ + PROCESSOR_OUTPUT_RESPONSE, /* IResponse */ +}; + typedef struct { DispatchEx dispex; @@ -38,8 +49,15 @@ typedef struct xsltemplate *stylesheet; IXMLDOMNode *input; - IStream *output; - BSTR outstr; + union + { + IUnknown *unk; + ISequentialStream *stream; + IPersistStream *persiststream; + IResponse *response; + } output; + enum output_type output_type; + BSTR outstr; struct xslprocessor_params params; } xslprocessor; @@ -298,7 +316,8 @@ static ULONG WINAPI xslprocessor_Release( IXSLProcessor *iface ) struct xslprocessor_par *par, *par2; if (This->input) IXMLDOMNode_Release(This->input); - if (This->output) IStream_Release(This->output); + if (This->output.unk) + IUnknown_Release(This->output.unk); SysFreeString(This->outstr); LIST_FOR_EACH_ENTRY_SAFE(par, par2, &This->params.list, struct xslprocessor_par, entry) @@ -437,34 +456,57 @@ static HRESULT WINAPI xslprocessor_get_startModeURI( static HRESULT WINAPI xslprocessor_put_output( IXSLProcessor *iface, - VARIANT output) + VARIANT var) { xslprocessor *This = impl_from_IXSLProcessor( iface ); - IStream *stream; - HRESULT hr; + enum output_type output_type = PROCESSOR_OUTPUT_NOT_SET; + IUnknown *output = NULL; + HRESULT hr = S_OK; - TRACE("(%p)->(%s)\n", This, debugstr_variant(&output)); + TRACE("(%p)->(%s)\n", This, debugstr_variant(&var)); - switch (V_VT(&output)) + switch (V_VT(&var)) { - case VT_EMPTY: - stream = NULL; - hr = S_OK; + case VT_EMPTY: break; - case VT_UNKNOWN: - hr = IUnknown_QueryInterface(V_UNKNOWN(&output), &IID_IStream, (void**)&stream); + case VT_UNKNOWN: + case VT_DISPATCH: + if (!V_UNKNOWN(&var)) + break; + + output_type = PROCESSOR_OUTPUT_STREAM; + hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IStream, (void **)&output); if (FAILED(hr)) - WARN("failed to get IStream from output, 0x%08x\n", hr); + hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_ISequentialStream, (void **)&output); + if (FAILED(hr)) + { + output_type = PROCESSOR_OUTPUT_RESPONSE; + hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IResponse, (void **)&output); + } + if (FAILED(hr)) + { + output_type = PROCESSOR_OUTPUT_PERSISTSTREAM; + hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IPersistStream, (void **)&output); + } + if (FAILED(hr)) + hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IPersistStreamInit, (void **)&output); + if (FAILED(hr)) + { + output_type = PROCESSOR_OUTPUT_NOT_SET; + WARN("failed to get output interface, 0x%08x\n", hr); + } break; - default: - FIXME("output type %d not handled\n", V_VT(&output)); + default: + FIXME("output type %d not handled\n", V_VT(&var)); hr = E_FAIL; } if (hr == S_OK) { - if (This->output) IStream_Release(This->output); - This->output = stream; + if (This->output.unk) + IUnknown_Release(This->output.unk); + This->output.unk = output; + This->output_type = output_type; } return hr; @@ -480,11 +522,11 @@ static HRESULT WINAPI xslprocessor_get_output( if (!output) return E_INVALIDARG; - if (This->output) + if (This->output.unk) { V_VT(output) = VT_UNKNOWN; - V_UNKNOWN(output) = (IUnknown*)This->output; - IStream_AddRef(This->output); + V_UNKNOWN(output) = This->output.unk; + IUnknown_AddRef(This->output.unk); } else if (This->outstr) { @@ -503,14 +545,89 @@ static HRESULT WINAPI xslprocessor_transform( { #ifdef HAVE_LIBXML2 xslprocessor *This = impl_from_IXSLProcessor( iface ); + ISequentialStream *stream = NULL; HRESULT hr; TRACE("(%p)->(%p)\n", This, ret); - if (!ret) return E_INVALIDARG; + if (!ret) + return E_INVALIDARG; + + if (This->output_type == PROCESSOR_OUTPUT_STREAM) + { + stream = This->output.stream; + ISequentialStream_AddRef(stream); + } + else if (This->output_type == PROCESSOR_OUTPUT_PERSISTSTREAM || + This->output_type == PROCESSOR_OUTPUT_RESPONSE) + { + if (FAILED(hr = CreateStreamOnHGlobal(NULL, TRUE, (IStream **)&stream))) + return hr; + } SysFreeString(This->outstr); - hr = node_transform_node_params(get_node_obj(This->input), This->stylesheet->node, &This->outstr, This->output, &This->params); + + hr = node_transform_node_params(get_node_obj(This->input), This->stylesheet->node, + &This->outstr, stream, &This->params); + if (SUCCEEDED(hr)) + { + IStream *src = (IStream *)stream; + + switch (This->output_type) + { + case PROCESSOR_OUTPUT_PERSISTSTREAM: + { + LARGE_INTEGER zero; + + /* for IPersistStream* output seekable stream is used */ + zero.QuadPart = 0; + IStream_Seek(src, zero, STREAM_SEEK_SET, NULL); + hr = IPersistStream_Load(This->output.persiststream, src); + break; + } + case PROCESSOR_OUTPUT_RESPONSE: + { + SAFEARRAYBOUND bound; + SAFEARRAY *array; + HGLOBAL hglobal; + VARIANT bin; + DWORD size; + void *dest; + + if (FAILED(hr = GetHGlobalFromStream(src, &hglobal))) + break; + size = GlobalSize(hglobal); + + bound.lLbound = 0; + bound.cElements = size; + if (!(array = SafeArrayCreate(VT_UI1, 1, &bound))) + break; + + V_VT(&bin) = VT_ARRAY | VT_UI1; + V_ARRAY(&bin) = array; + + hr = SafeArrayAccessData(array, &dest); + if (hr == S_OK) + { + void *data = GlobalLock(hglobal); + memcpy(dest, data, size); + GlobalUnlock(hglobal); + SafeArrayUnaccessData(array); + + IResponse_BinaryWrite(This->output.response, bin); + } + + VariantClear(&bin); + break; + } + default: + ; + } + } + + if (stream) + ISequentialStream_Release(stream); + *ret = hr == S_OK ? VARIANT_TRUE : VARIANT_FALSE; return hr; #else @@ -689,7 +806,8 @@ HRESULT XSLProcessor_create(xsltemplate *template, IXSLProcessor **ppObj) This->IXSLProcessor_iface.lpVtbl = &XSLProcessorVtbl; This->ref = 1; This->input = NULL; - This->output = NULL; + This->output.unk = NULL; + This->output_type = PROCESSOR_OUTPUT_NOT_SET; This->outstr = NULL; list_init(&This->params.list); This->params.count = 0; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index c4512fef64c..5b33012a559 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -129,7 +129,7 @@ reactos/dll/win32/msvfw32 # Synced to WineStaging-2.2 reactos/dll/win32/msvidc32 # Synced to WineStaging-1.9.11 reactos/dll/win32/msxml # Synced to WineStaging-1.9.11 reactos/dll/win32/msxml2 # Synced to WineStaging-1.9.11 -reactos/dll/win32/msxml3 # Synced to WineStaging-2.2 +reactos/dll/win32/msxml3 # Synced to WineStaging-2.9 reactos/dll/win32/msxml4 # Synced to WineStaging-1.9.11 reactos/dll/win32/msxml6 # Synced to WineStaging-1.9.11 reactos/dll/win32/nddeapi # Synced to WineStaging-1.9.11