diff --git a/dlls/msxml3/stylesheet.c b/dlls/msxml3/stylesheet.c index 6d7507e398a..b1f79721f7a 100644 --- a/dlls/msxml3/stylesheet.c +++ b/dlls/msxml3/stylesheet.c @@ -51,6 +51,7 @@ typedef struct _xslprocessor LONG ref; IXMLDOMNode *input; + IStream *output; } xslprocessor; static HRESULT XSLProcessor_create(IXSLProcessor**); @@ -306,6 +307,7 @@ static ULONG WINAPI xslprocessor_Release( IXSLProcessor *iface ) if ( ref == 0 ) { if (This->input) IXMLDOMNode_Release(This->input); + if (This->output) IStream_Release(This->output); heap_free( This ); } @@ -475,9 +477,31 @@ static HRESULT WINAPI xslprocessor_put_output( VARIANT output) { xslprocessor *This = impl_from_IXSLProcessor( iface ); + IStream *stream; + HRESULT hr; - FIXME("(%p): stub\n", This); - return E_NOTIMPL; + FIXME("(%p)->(%s): semi-stub\n", This, debugstr_variant(&output)); + + switch (V_VT(&output)) + { + case VT_EMPTY: + stream = NULL; + hr = S_OK; + break; + case VT_UNKNOWN: + hr = IUnknown_QueryInterface(V_UNKNOWN(&output), &IID_IStream, (void**)&stream); + break; + default: + hr = E_FAIL; + } + + if (hr == S_OK) + { + if (This->output) IStream_Release(This->output); + This->output = stream; + } + + return hr; } static HRESULT WINAPI xslprocessor_get_output( @@ -590,6 +614,7 @@ HRESULT XSLProcessor_create(IXSLProcessor **ppObj) This->IXSLProcessor_iface.lpVtbl = &xslprocessor_vtbl; This->ref = 1; This->input = NULL; + This->output = NULL; *ppObj = &This->IXSLProcessor_iface; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 0c8fff2cc08..d85c6784029 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -7663,9 +7663,10 @@ static void test_xsltemplate(void) IXSLTemplate *template; IXSLProcessor *processor; IXMLDOMDocument *doc; + IStream *stream; VARIANT_BOOL b; HRESULT hr; - ULONG ref1, ref2; + ULONG ref1, ref2, ref; VARIANT v; template = create_xsltemplate(&IID_IXSLTemplate); @@ -7734,6 +7735,37 @@ todo_wine { ok(hr == S_OK, "got 0x%08x\n", hr); ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v)); } + + /* reset before it was set */ + V_VT(&v) = VT_EMPTY; + hr = IXSLProcessor_put_output(processor, v); + ok(hr == S_OK, "got 0x%08x\n", hr); + + CreateStreamOnHGlobal(NULL, TRUE, &stream); + ref = IStream_AddRef(stream); + IStream_Release(stream); + ok(ref == 2, "got %d\n", ref); + + V_VT(&v) = VT_UNKNOWN; + V_UNKNOWN(&v) = (IUnknown*)stream; + hr = IXSLProcessor_put_output(processor, v); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* it seems processor grabs 2 references */ + ref = IStream_AddRef(stream); + IStream_Release(stream); + todo_wine ok(ref == 4, "got %d\n", ref); + + /* reset and check stream refcount */ + V_VT(&v) = VT_EMPTY; + hr = IXSLProcessor_put_output(processor, v); + ok(hr == S_OK, "got 0x%08x\n", hr); + + ref = IStream_AddRef(stream); + IStream_Release(stream); + ok(ref == 2, "got %d\n", ref); + + IStream_Release(stream); IXSLProcessor_Release(processor); /* drop reference */