ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
June 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
26 participants
174 discussions
Start a n
N
ew thread
01/01: [VBSCRIPT_WINETEST] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c78e87365225bd040f374…
commit c78e87365225bd040f374dc41e32bcd4ae77aa6d Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:53:02 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:53:02 2018 +0100 [VBSCRIPT_WINETEST] Sync with Wine Staging 3.9. CORE-14656 --- modules/rostests/winetests/vbscript/run.c | 73 ++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/modules/rostests/winetests/vbscript/run.c b/modules/rostests/winetests/vbscript/run.c index ee811c6e5b..6b57540fe8 100644 --- a/modules/rostests/winetests/vbscript/run.c +++ b/modules/rostests/winetests/vbscript/run.c @@ -974,6 +974,18 @@ static IDispatchExVtbl RefObjVtbl = { static IDispatchEx RefObj = { &RefObjVtbl }; +static ULONG global_ref; + +static ULONG WINAPI Global_AddRef(IDispatchEx *iface) +{ + return ++global_ref; +} + +static ULONG WINAPI Global_Release(IDispatchEx *iface) +{ + return --global_ref; +} + static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { if(!strcmp_wa(bstrName, "ok")) { @@ -1476,8 +1488,8 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, static IDispatchExVtbl GlobalVtbl = { DispatchEx_QueryInterface, - DispatchEx_AddRef, - DispatchEx_Release, + Global_AddRef, + Global_Release, DispatchEx_GetTypeInfoCount, DispatchEx_GetTypeInfo, DispatchEx_GetIDsOfNames, @@ -1619,6 +1631,7 @@ static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPC ok(0, "unexpected pstrName %s\n", wine_dbgstr_w(pstrName)); *ppiunkItem = (IUnknown*)&Global; + IUnknown_AddRef(*ppiunkItem); return S_OK; } @@ -1804,6 +1817,61 @@ static HRESULT parse_script_ar(const char *src) return hres; } +static void test_parse_context(void) +{ + IActiveScriptParse *parser; + IActiveScript *engine; + BSTR str; + HRESULT hres; + + static const WCHAR xW[] = {'x',0}; + static const WCHAR yW[] = {'y',0}; + + global_ref = 1; + engine = create_and_init_script(0); + if(!engine) + return; + + hres = IActiveScript_QueryInterface(engine, &IID_IActiveScriptParse, (void**)&parser); + ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres); + + /* unknown identifier context is not a valid argument */ + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, yW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + str = a2bstr("class Cl\n" + " Public Sub ClMethod\n" + " Call reportSuccess()\n" + " End Sub\n" + "End Class\n" + "Dim x\n" + "set x = new Cl\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + /* known global variable is not a valid context */ + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, xW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + + SET_EXPECT(global_success_d); + SET_EXPECT(global_success_i); + str = a2bstr("Call reportSuccess()\n"); + hres = IActiveScriptParse_ParseScriptText(parser, str, testW, NULL, NULL, 0, 0, 0, NULL, NULL); + ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres); + SysFreeString(str); + CHECK_CALLED(global_success_d); + CHECK_CALLED(global_success_i); + + IActiveScriptParse_Release(parser); + close_script(engine); + ok(global_ref == 1, "global_ref = %u\n", global_ref); +} + static void parse_script_a(const char *src) { parse_script_af(SCRIPTITEM_GLOBALMEMBERS, src); @@ -2334,6 +2402,7 @@ static void run_tests(void) test_procedures(); test_gc(); test_msgbox(); + test_parse_context(); } static BOOL check_vbscript(void)
6 years, 6 months
1
0
0
0
01/01: [VBSCRIPT] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bcea8c65d05c0a699765f…
commit bcea8c65d05c0a699765fc8c0a8be42f1cb394e5 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:52:36 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:52:36 2018 +0100 [VBSCRIPT] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/vbscript/compile.c | 15 ++---- dll/win32/vbscript/interp.c | 39 +++++++-------- dll/win32/vbscript/vbscript.c | 109 ++++++++++++++++++++++++++++++++++++++++++ dll/win32/vbscript/vbscript.h | 3 ++ media/doc/README.WINE | 2 +- 5 files changed, 132 insertions(+), 36 deletions(-) diff --git a/dll/win32/vbscript/compile.c b/dll/win32/vbscript/compile.c index c8189d6d96..302804f4c2 100644 --- a/dll/win32/vbscript/compile.c +++ b/dll/win32/vbscript/compile.c @@ -1746,6 +1746,8 @@ void release_vbscode(vbscode_t *code) for(i=0; i < code->bstr_cnt; i++) SysFreeString(code->bstr_pool[i]); + if(code->context) + IDispatch_Release(code->context); heap_pool_free(&code->heap); heap_free(code->bstr_pool); @@ -1758,7 +1760,7 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source) { vbscode_t *ret; - ret = heap_alloc(sizeof(*ret)); + ret = heap_alloc_zero(sizeof(*ret)); if(!ret) return NULL; @@ -1780,19 +1782,8 @@ static vbscode_t *alloc_vbscode(compile_ctx_t *ctx, const WCHAR *source) ret->option_explicit = ctx->parser.option_explicit; - ret->bstr_pool = NULL; - ret->bstr_pool_size = 0; - ret->bstr_cnt = 0; - ret->pending_exec = FALSE; - ret->main_code.type = FUNC_GLOBAL; - ret->main_code.name = NULL; ret->main_code.code_ctx = ret; - ret->main_code.vars = NULL; - ret->main_code.var_cnt = 0; - ret->main_code.array_cnt = 0; - ret->main_code.arg_cnt = 0; - ret->main_code.args = NULL; list_init(&ret->entry); return ret; diff --git a/dll/win32/vbscript/interp.c b/dll/win32/vbscript/interp.c index 9ec329924c..b46bd01c0f 100644 --- a/dll/win32/vbscript/interp.c +++ b/dll/win32/vbscript/interp.c @@ -99,6 +99,7 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ { named_item_t *item; function_t *func; + IDispatch *disp; unsigned i; DISPID id; HRESULT hres; @@ -153,6 +154,16 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ } } + if(ctx->func->code_ctx->context) { + hres = disp_get_id(ctx->func->code_ctx->context, name, invoke_type, TRUE, &id); + if(SUCCEEDED(hres)) { + ref->type = REF_DISP; + ref->u.d.disp = ctx->func->code_ctx->context; + ref->u.d.id = id; + return S_OK; + } + } + if(ctx->func->type != FUNC_GLOBAL && lookup_dynamic_vars(ctx->script->global_vars, name, ref)) return S_OK; @@ -178,29 +189,11 @@ static HRESULT lookup_identifier(exec_ctx_t *ctx, BSTR name, vbdisp_invoke_type_ return S_OK; } - LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) { - if((item->flags & SCRIPTITEM_ISVISIBLE) && !strcmpiW(item->name, name)) { - if(!item->disp) { - IUnknown *unk; - - hres = IActiveScriptSite_GetItemInfo(ctx->script->site, item->name, SCRIPTINFO_IUNKNOWN, &unk, NULL); - if(FAILED(hres)) { - WARN("GetItemInfo failed: %08x\n", hres); - continue; - } - - hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp); - IUnknown_Release(unk); - if(FAILED(hres)) { - WARN("object does not implement IDispatch\n"); - continue; - } - } - - ref->type = REF_OBJ; - ref->u.obj = item->disp; - return S_OK; - } + disp = lookup_named_item(ctx->script, name, SCRIPTITEM_ISVISIBLE); + if(disp) { + ref->type = REF_OBJ; + ref->u.obj = disp; + return S_OK; } LIST_FOR_EACH_ENTRY(item, &ctx->script->named_items, named_item_t, entry) { diff --git a/dll/win32/vbscript/vbscript.c b/dll/win32/vbscript/vbscript.c index 645068e347..06a855b2b3 100644 --- a/dll/win32/vbscript/vbscript.c +++ b/dll/win32/vbscript/vbscript.c @@ -29,12 +29,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(vbscript); #ifdef _WIN64 #define CTXARG_T DWORDLONG +#define IActiveScriptDebugVtbl IActiveScriptDebug64Vtbl #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl #else #define CTXARG_T DWORD +#define IActiveScriptDebugVtbl IActiveScriptDebug32Vtbl #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl @@ -42,6 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vbscript); struct VBScript { IActiveScript IActiveScript_iface; + IActiveScriptDebug IActiveScriptDebug_iface; IActiveScriptParse IActiveScriptParse_iface; IActiveScriptParseProcedure2 IActiveScriptParseProcedure2_iface; IObjectSafety IObjectSafety_iface; @@ -96,6 +99,38 @@ static void exec_queued_code(script_ctx_t *ctx) } } +IDispatch *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned flags) +{ + named_item_t *item; + HRESULT hres; + + LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) { + if((item->flags & flags) == flags && !strcmpiW(item->name, name)) { + if(!item->disp) { + IUnknown *unk; + + hres = IActiveScriptSite_GetItemInfo(ctx->site, item->name, + SCRIPTINFO_IUNKNOWN, &unk, NULL); + if(FAILED(hres)) { + WARN("GetItemInfo failed: %08x\n", hres); + continue; + } + + hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&item->disp); + IUnknown_Release(unk); + if(FAILED(hres)) { + WARN("object does not implement IDispatch\n"); + continue; + } + } + + return item->disp; + } + } + + return NULL; +} + static HRESULT set_ctx_site(VBScript *This) { HRESULT hres; @@ -235,6 +270,9 @@ static HRESULT WINAPI VBScript_QueryInterface(IActiveScript *iface, REFIID riid, }else if(IsEqualGUID(riid, &IID_IActiveScript)) { TRACE("(%p)->(IID_IActiveScript %p)\n", This, ppv); *ppv = &This->IActiveScript_iface; + }else if(IsEqualGUID(riid, &IID_IActiveScriptDebug)) { + TRACE("(%p)->(IID_IActiveScriptDebug %p)\n", This, ppv); + *ppv = &This->IActiveScriptDebug_iface; }else if(IsEqualGUID(riid, &IID_IActiveScriptParse)) { TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This, ppv); *ppv = &This->IActiveScriptParse_iface; @@ -532,6 +570,64 @@ static const IActiveScriptVtbl VBScriptVtbl = { VBScript_Clone }; +static inline VBScript *impl_from_IActiveScriptDebug(IActiveScriptDebug *iface) +{ + return CONTAINING_RECORD(iface, VBScript, IActiveScriptDebug_iface); +} + +static HRESULT WINAPI VBScriptDebug_QueryInterface(IActiveScriptDebug *iface, REFIID riid, void **ppv) +{ + VBScript *This = impl_from_IActiveScriptDebug(iface); + return IActiveScript_QueryInterface(&This->IActiveScript_iface, riid, ppv); +} + +static ULONG WINAPI VBScriptDebug_AddRef(IActiveScriptDebug *iface) +{ + VBScript *This = impl_from_IActiveScriptDebug(iface); + return IActiveScript_AddRef(&This->IActiveScript_iface); +} + +static ULONG WINAPI VBScriptDebug_Release(IActiveScriptDebug *iface) +{ + VBScript *This = impl_from_IActiveScriptDebug(iface); + return IActiveScript_Release(&This->IActiveScript_iface); +} + +static HRESULT WINAPI VBScriptDebug_GetScriptTextAttributes(IActiveScriptDebug *iface, + LPCOLESTR code, ULONG len, LPCOLESTR delimiter, DWORD flags, SOURCE_TEXT_ATTR *attr) +{ + VBScript *This = impl_from_IActiveScriptDebug(iface); + FIXME("(%p)->(%s %u %s %#x %p)\n", This, debugstr_w(code), len, + debugstr_w(delimiter), flags, attr); + return E_NOTIMPL; +} + +static HRESULT WINAPI VBScriptDebug_GetScriptletTextAttributes(IActiveScriptDebug *iface, + LPCOLESTR code, ULONG len, LPCOLESTR delimiter, DWORD flags, SOURCE_TEXT_ATTR *attr) +{ + VBScript *This = impl_from_IActiveScriptDebug(iface); + FIXME("(%p)->(%s %u %s %#x %p)\n", This, debugstr_w(code), len, + debugstr_w(delimiter), flags, attr); + return E_NOTIMPL; +} + +static HRESULT WINAPI VBScriptDebug_EnumCodeContextsOfPosition(IActiveScriptDebug *iface, + CTXARG_T source, ULONG offset, ULONG len, IEnumDebugCodeContexts **ret) +{ + VBScript *This = impl_from_IActiveScriptDebug(iface); + FIXME("(%p)->(%s %u %u %p)\n", This, wine_dbgstr_longlong(source), offset, len, ret); + return E_NOTIMPL; +} + +static const IActiveScriptDebugVtbl VBScriptDebugVtbl = { + VBScriptDebug_QueryInterface, + VBScriptDebug_AddRef, + VBScriptDebug_Release, + VBScriptDebug_GetScriptTextAttributes, + VBScriptDebug_GetScriptletTextAttributes, + VBScriptDebug_EnumCodeContextsOfPosition, +}; + static inline VBScript *impl_from_IActiveScriptParse(IActiveScriptParse *iface) { return CONTAINING_RECORD(iface, VBScript, IActiveScriptParse_iface); @@ -604,6 +700,7 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) { VBScript *This = impl_from_IActiveScriptParse(iface); + IDispatch *context = NULL; vbscode_t *code; HRESULT hres; @@ -614,10 +711,21 @@ static HRESULT WINAPI VBScriptParse_ParseScriptText(IActiveScriptParse *iface, if(This->thread_id != GetCurrentThreadId() || This->state == SCRIPTSTATE_CLOSED) return E_UNEXPECTED; + if(pstrItemName) { + context = lookup_named_item(This->ctx, pstrItemName, 0); + if(!context) { + WARN("Inknown context %s\n", debugstr_w(pstrItemName)); + return E_INVALIDARG; + } + } + hres = compile_script(This->ctx, pstrCode, pstrDelimiter, &code); if(FAILED(hres)) return hres; + if(context) + IDispatch_AddRef(code->context = context); + if(!is_started(This)) { code->pending_exec = TRUE; return S_OK; @@ -762,6 +870,7 @@ HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pU return E_OUTOFMEMORY; ret->IActiveScript_iface.lpVtbl = &VBScriptVtbl; + ret->IActiveScriptDebug_iface.lpVtbl = &VBScriptDebugVtbl; ret->IActiveScriptParse_iface.lpVtbl = &VBScriptParseVtbl; ret->IActiveScriptParseProcedure2_iface.lpVtbl = &VBScriptParseProcedureVtbl; ret->IObjectSafety_iface.lpVtbl = &VBScriptSafetyVtbl; diff --git a/dll/win32/vbscript/vbscript.h b/dll/win32/vbscript/vbscript.h index 94fdefe277..5558dc3e87 100644 --- a/dll/win32/vbscript/vbscript.h +++ b/dll/win32/vbscript/vbscript.h @@ -27,6 +27,7 @@ #include "ole2.h" #include "dispex.h" #include "activscp.h" +#include "activdbg.h" #ifdef __REACTOS__ #include <initguid.h> @@ -347,6 +348,7 @@ struct _vbscode_t { BOOL pending_exec; function_t main_code; + IDispatch *context; BSTR *bstr_pool; unsigned bstr_pool_size; @@ -360,6 +362,7 @@ void release_vbscode(vbscode_t*) DECLSPEC_HIDDEN; HRESULT compile_script(script_ctx_t*,const WCHAR*,const WCHAR*,vbscode_t**) DECLSPEC_HIDDEN; HRESULT exec_script(script_ctx_t*,function_t*,vbdisp_t*,DISPPARAMS*,VARIANT*) DECLSPEC_HIDDEN; void release_dynamic_vars(dynamic_var_t*) DECLSPEC_HIDDEN; +IDispatch *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN; typedef struct { UINT16 len; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 20f1cfb5a2..56945ecaf9 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -191,7 +191,7 @@ reactos/dll/win32/url # Synced to WineStaging-3.3 reactos/dll/win32/urlmon # Synced to WineStaging-3.9 reactos/dll/win32/usp10 # Synced to WineStaging-3.9 reactos/dll/win32/uxtheme # Forked -reactos/dll/win32/vbscript # Synced to WineStaging-3.3 +reactos/dll/win32/vbscript # Synced to WineStaging-3.9 reactos/dll/win32/version # Synced to WineStaging-3.3 reactos/dll/win32/vssapi # Synced to WineStaging-2.9 reactos/dll/win32/wbemdisp # Synced to WineStaging-3.3
6 years, 6 months
1
0
0
0
01/01: [USP10_WINETEST] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=af009ed327aad61f1fc75…
commit af009ed327aad61f1fc75534d023fc5c96b916e1 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:51:59 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:51:59 2018 +0100 [USP10_WINETEST] Sync with Wine Staging 3.9. CORE-14656 --- modules/rostests/winetests/usp10/usp10.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/rostests/winetests/usp10/usp10.c b/modules/rostests/winetests/usp10/usp10.c index f548b5792c..aa26997112 100644 --- a/modules/rostests/winetests/usp10/usp10.c +++ b/modules/rostests/winetests/usp10/usp10.c @@ -31,10 +31,6 @@ #include <windows.h> #include <usp10.h> -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) -#endif - typedef struct _itemTest { char todo_flag[6]; int iCharPos;
6 years, 6 months
1
0
0
0
01/01: [USP10] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aa15c73fc5c100d75457c…
commit aa15c73fc5c100d75457c5caa95f13bce4db8cd3 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:51:34 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:51:34 2018 +0100 [USP10] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/usp10/bidi.c | 2 +- dll/win32/usp10/opentype.c | 286 +++++++++++++++------------------------ dll/win32/usp10/shape.c | 8 +- dll/win32/usp10/usp10.c | 72 +++++----- dll/win32/usp10/usp10_internal.h | 23 +++- media/doc/README.WINE | 2 +- 6 files changed, 170 insertions(+), 223 deletions(-) diff --git a/dll/win32/usp10/bidi.c b/dll/win32/usp10/bidi.c index b0df781c82..0fb03ef061 100644 --- a/dll/win32/usp10/bidi.c +++ b/dll/win32/usp10/bidi.c @@ -998,7 +998,7 @@ static void computeIsolatingRunsSet(unsigned baselevel, WORD *pcls, const WORD * Run *runs; IsolatedRun *current_isolated; - if (!(runs = heap_alloc(uCount * sizeof(*runs)))) + if (!(runs = heap_calloc(uCount, sizeof(*runs)))) return; list_init(set); diff --git a/dll/win32/usp10/opentype.c b/dll/win32/usp10/opentype.c index 2d708a8c40..53632714a4 100644 --- a/dll/win32/usp10/opentype.c +++ b/dll/win32/usp10/opentype.c @@ -2565,6 +2565,23 @@ unsigned int OpenType_apply_GPOS_lookup(const ScriptCache *script_cache, const O lookup_index, glyphs, glyph_index, glyph_count, goffset); } +static LoadedScript *usp10_script_cache_add_script(ScriptCache *script_cache, OPENTYPE_TAG tag) +{ + LoadedScript *script; + + if (!usp10_array_reserve((void **)&script_cache->scripts, &script_cache->scripts_size, + script_cache->script_count + 1, sizeof(*script_cache->scripts))) + { + ERR("Failed to grow scripts array.\n"); + return NULL; + } + + script = &script_cache->scripts[script_cache->script_count++]; + script->tag = tag; + + return script; +} + static LoadedScript *usp10_script_cache_get_script(ScriptCache *script_cache, OPENTYPE_TAG tag) { size_t i; @@ -2578,94 +2595,53 @@ static LoadedScript *usp10_script_cache_get_script(ScriptCache *script_cache, OP return NULL; } -static void GSUB_initialize_script_cache(ScriptCache *psc) +static void usp10_script_cache_add_script_list(ScriptCache *script_cache, + enum usp10_script_table table, const OT_ScriptList *list) { - int i; - - if (psc->GSUB_Table) - { - const OT_ScriptList *script; - const GSUB_Header* header = (const GSUB_Header*)psc->GSUB_Table; - script = (const OT_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList)); - psc->script_count = GET_BE_WORD(script->ScriptCount); - TRACE("initializing %li scripts in this font\n",psc->script_count); - if (psc->script_count) - { - psc->scripts = heap_alloc_zero(psc->script_count * sizeof(*psc->scripts)); - for (i = 0; i < psc->script_count; i++) - { - int offset = GET_BE_WORD(script->ScriptRecord[i].Script); - psc->scripts[i].tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]); - psc->scripts[i].gsub_table = ((const BYTE*)script + offset); - } - } - } -} + SIZE_T initial_count, count, i; + LoadedScript *script; + OPENTYPE_TAG tag; -static void GPOS_expand_script_cache(ScriptCache *psc) -{ - int i, count; - const OT_ScriptList *script; - const GPOS_Header* header = (const GPOS_Header*)psc->GPOS_Table; - LoadedScript *loaded_script; + TRACE("script_cache %p, table %#x, list %p.\n", script_cache, table, list); - if (!header) + if (!(count = GET_BE_WORD(list->ScriptCount))) return; - script = (const OT_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList)); - count = GET_BE_WORD(script->ScriptCount); + TRACE("Adding %lu scripts.\n", count); - if (!count) - return; - - if (!psc->script_count) - { - psc->script_count = count; - TRACE("initializing %li scripts in this font\n",psc->script_count); - if (psc->script_count) - { - psc->scripts = heap_alloc_zero(psc->script_count * sizeof(*psc->scripts)); - for (i = 0; i < psc->script_count; i++) - { - int offset = GET_BE_WORD(script->ScriptRecord[i].Script); - psc->scripts[i].tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]); - psc->scripts[i].gpos_table = ((const BYTE*)script + offset); - } - } - } - else + initial_count = script_cache->script_count; + for (i = 0; i < count; ++i) { - for (i = 0; i < count; i++) - { - int offset = GET_BE_WORD(script->ScriptRecord[i].Script); - OPENTYPE_TAG tag = MS_MAKE_TAG(script->ScriptRecord[i].ScriptTag[0], script->ScriptRecord[i].ScriptTag[1], script->ScriptRecord[i].ScriptTag[2], script->ScriptRecord[i].ScriptTag[3]); + tag = MS_MAKE_TAG(list->ScriptRecord[i].ScriptTag[0], + list->ScriptRecord[i].ScriptTag[1], + list->ScriptRecord[i].ScriptTag[2], + list->ScriptRecord[i].ScriptTag[3]); - if (!(loaded_script = usp10_script_cache_get_script(psc, tag))) - { - if (!usp10_array_reserve((void **)&psc->scripts, &psc->scripts_size, - psc->script_count + 1, sizeof(*psc->scripts))) - { - ERR("Failed grow scripts array.\n"); - return; - } + if (!(initial_count && (script = usp10_script_cache_get_script(script_cache, tag))) + && !(script = usp10_script_cache_add_script(script_cache, tag))) + return; - loaded_script = &psc->scripts[psc->script_count]; - ++psc->script_count; - loaded_script->tag = tag; - } - loaded_script->gpos_table = (const BYTE *)script + offset; - } + script->table[table] = (const BYTE *)list + GET_BE_WORD(list->ScriptRecord[i].Script); } } -static void _initialize_script_cache(ScriptCache *psc) +static void _initialize_script_cache(ScriptCache *script_cache) { - if (!psc->scripts_initialized) - { - GSUB_initialize_script_cache(psc); - GPOS_expand_script_cache(psc); - psc->scripts_initialized = TRUE; - } + const GPOS_Header *gpos_header; + const GSUB_Header *gsub_header; + + if (script_cache->scripts_initialized) + return; + + if ((gsub_header = script_cache->GSUB_Table)) + usp10_script_cache_add_script_list(script_cache, USP10_SCRIPT_TABLE_GSUB, + (const OT_ScriptList *)((const BYTE *)gsub_header + GET_BE_WORD(gsub_header->ScriptList))); + + if ((gpos_header = script_cache->GPOS_Table)) + usp10_script_cache_add_script_list(script_cache, USP10_SCRIPT_TABLE_GPOS, + (const OT_ScriptList *)((const BYTE *)gpos_header + GET_BE_WORD(gpos_header->ScriptList))); + + script_cache->scripts_initialized = TRUE; } HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags) @@ -2699,120 +2675,87 @@ HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, return rc; } -static LoadedLanguage *usp10_script_get_language(LoadedScript *script, OPENTYPE_TAG tag) +static LoadedLanguage *usp10_script_add_language(LoadedScript *script, OPENTYPE_TAG tag) { - size_t i; + LoadedLanguage *language; - for (i = 0; i < script->language_count; ++i) + if (!usp10_array_reserve((void **)&script->languages, &script->languages_size, + script->language_count + 1, sizeof(*script->languages))) { - if (script->languages[i].tag == tag) - return &script->languages[i]; + ERR("Failed to grow languages array.\n"); + return NULL; } - return NULL; + language = &script->languages[script->language_count++]; + language->tag = tag; + + return language; } -static void GSUB_initialize_language_cache(LoadedScript *script) +static LoadedLanguage *usp10_script_get_language(LoadedScript *script, OPENTYPE_TAG tag) { - int i; + size_t i; - if (script->gsub_table) + for (i = 0; i < script->language_count; ++i) { - DWORD offset; - const OT_Script* table = script->gsub_table; - script->language_count = GET_BE_WORD(table->LangSysCount); - offset = GET_BE_WORD(table->DefaultLangSys); - if (offset) - { - script->default_language.tag = MS_MAKE_TAG('d','f','l','t'); - script->default_language.gsub_table = (const BYTE*)table + offset; - } - - if (script->language_count) - { - TRACE("Deflang %p, LangCount %li\n",script->default_language.gsub_table, script->language_count); - - script->languages = heap_alloc_zero(script->language_count * sizeof(*script->languages)); - - for (i = 0; i < script->language_count; i++) - { - int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys); - script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]); - script->languages[i].gsub_table = ((const BYTE*)table + offset); - } - } + if (script->languages[i].tag == tag) + return &script->languages[i]; } + + return NULL; } -static void GPOS_expand_language_cache(LoadedScript *script) +static void usp10_script_add_language_list(LoadedScript *script, + enum usp10_language_table table, const OT_Script *list) { - int count; - const OT_Script* table = script->gpos_table; + SIZE_T initial_count, count, i; LoadedLanguage *language; + OPENTYPE_TAG tag; DWORD offset; - if (!table) - return; - - offset = GET_BE_WORD(table->DefaultLangSys); - if (offset) - script->default_language.gpos_table = (const BYTE*)table + offset; - - count = GET_BE_WORD(table->LangSysCount); + TRACE("script %p, table %#x, list %p.\n", script, table, list); - TRACE("Deflang %p, LangCount %i\n",script->default_language.gpos_table, count); + if ((offset = GET_BE_WORD(list->DefaultLangSys))) + { + script->default_language.tag = MS_MAKE_TAG('d','f','l','t'); + script->default_language.table[table] = (const BYTE *)list + offset; + TRACE("Default language %p.\n", script->default_language.table[table]); + } - if (!count) + if (!(count = GET_BE_WORD(list->LangSysCount))) return; - if (!script->language_count) - { - int i; - script->language_count = count; - - script->languages = heap_alloc_zero(script->language_count * sizeof(*script->languages)); + TRACE("Adding %lu languages.\n", count); - for (i = 0; i < script->language_count; i++) - { - int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys); - script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]); - script->languages[i].gpos_table = ((const BYTE*)table + offset); - } - } - else if (count) + initial_count = script->language_count; + for (i = 0; i < count; ++i) { - int i; - for (i = 0; i < count; i++) - { - int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys); - OPENTYPE_TAG tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]); + tag = MS_MAKE_TAG(list->LangSysRecord[i].LangSysTag[0], + list->LangSysRecord[i].LangSysTag[1], + list->LangSysRecord[i].LangSysTag[2], + list->LangSysRecord[i].LangSysTag[3]); - if (!(language = usp10_script_get_language(script, tag))) - { - if (!usp10_array_reserve((void **)&script->languages, &script->languages_size, - script->language_count + 1, sizeof(*script->languages))) - { - ERR("Failed grow languages array.\n"); - return; - } + if (!(initial_count && (language = usp10_script_get_language(script, tag))) + && !(language = usp10_script_add_language(script, tag))) + return; - language = &script->languages[script->language_count]; - ++script->language_count; - language->tag = tag; - } - language->gpos_table = (const BYTE *)table + offset; - } + language->table[table] = (const BYTE *)list + GET_BE_WORD(list->LangSysRecord[i].LangSys); } } static void _initialize_language_cache(LoadedScript *script) { - if (!script->languages_initialized) - { - GSUB_initialize_language_cache(script); - GPOS_expand_language_cache(script); - script->languages_initialized = TRUE; - } + const OT_Script *list; + + if (script->languages_initialized) + return; + + if ((list = script->table[USP10_SCRIPT_TABLE_GSUB])) + usp10_script_add_language_list(script, USP10_LANGUAGE_TABLE_GSUB, list); + if ((list = script->table[USP10_SCRIPT_TABLE_GPOS])) + usp10_script_add_language_list(script, USP10_LANGUAGE_TABLE_GPOS, list); + + script->languages_initialized = TRUE; } HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags) @@ -2851,7 +2794,7 @@ HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, } } - if (script->default_language.gsub_table) + if (script->default_language.table[USP10_LANGUAGE_TABLE_GSUB]) { if (i < cMaxTags) pLanguageTags[i] = script->default_language.tag; @@ -2875,15 +2818,10 @@ static void usp10_language_add_feature_list(LoadedLanguage *language, char table TRACE("table_type %#x, %u features.\n", table_type, count); - if (!count) + if (!count || !usp10_array_reserve((void **)&language->features, &language->features_size, + language->feature_count + count, sizeof(*language->features))) return; - if (!language->feature_count) - language->features = heap_alloc(count * sizeof(*language->features)); - else - language->features = HeapReAlloc(GetProcessHeap(), 0, language->features, - (language->feature_count + count) * sizeof(*language->features)); - for (i = 0; i < count; ++i) { const OT_FeatureRecord *record; @@ -2899,7 +2837,7 @@ static void usp10_language_add_feature_list(LoadedLanguage *language, char table loaded_feature->tableType = table_type; loaded_feature->feature = feature; loaded_feature->lookup_count = GET_BE_WORD(feature->LookupCount); - loaded_feature->lookups = heap_alloc(loaded_feature->lookup_count * sizeof(*loaded_feature->lookups)); + loaded_feature->lookups = heap_calloc(loaded_feature->lookup_count, sizeof(*loaded_feature->lookups)); for (j = 0; j < loaded_feature->lookup_count; ++j) loaded_feature->lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]); } @@ -2916,13 +2854,13 @@ static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language if (language->features_initialized) return; - if ((lang = language->gsub_table)) + if ((lang = language->table[USP10_LANGUAGE_TABLE_GSUB])) { feature_list = (const OT_FeatureList *)((const BYTE *)gsub_header + GET_BE_WORD(gsub_header->FeatureList)); usp10_language_add_feature_list(language, FEATURE_GSUB_TABLE, lang, feature_list); } - if ((lang = language->gpos_table)) + if ((lang = language->table[USP10_LANGUAGE_TABLE_GPOS])) { feature_list = (const OT_FeatureList *)((const BYTE *)gpos_header + GET_BE_WORD(gpos_header->FeatureList)); usp10_language_add_feature_list(language, FEATURE_GPOS_TABLE, lang, feature_list); @@ -2934,9 +2872,9 @@ static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, char tableType, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature) { int i; + LoadedLanguage *language; LoadedScript *script; HRESULT rc = S_OK; - LoadedLanguage *language = NULL; _initialize_script_cache(psc); if (!(script = usp10_script_cache_get_script(psc, script_tag))) @@ -2950,9 +2888,9 @@ HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, O _initialize_language_cache(script); - if ((script->default_language.gsub_table || script->default_language.gpos_table) && script->default_language.tag == language_tag) - language = &script->default_language; - else + language = &script->default_language; + if (language->tag != language_tag || (!language->table[USP10_LANGUAGE_TABLE_GSUB] + && !language->table[USP10_LANGUAGE_TABLE_GPOS])) language = usp10_script_get_language(script, language_tag); if (!language) diff --git a/dll/win32/usp10/shape.c b/dll/win32/usp10/shape.c index ca084e7285..3827000122 100644 --- a/dll/win32/usp10/shape.c +++ b/dll/win32/usp10/shape.c @@ -712,13 +712,14 @@ static VOID load_ot_tables(HDC hdc, ScriptCache *psc) psc->GDEF_Table = load_gdef_table(hdc); } -INT SHAPE_does_GSUB_feature_apply_to_chars(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, const WCHAR *chars, INT write_dir, INT count, const char* feature) +int SHAPE_does_GSUB_feature_apply_to_chars(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache *psc, + const WCHAR *chars, int write_dir, int count, const char *feature) { WORD *glyphs; INT glyph_count = count; INT rc; - glyphs = heap_alloc(2 * count * sizeof(*glyphs)); + glyphs = heap_calloc(count, 2 * sizeof(*glyphs)); GetGlyphIndicesW(hdc, chars, count, glyphs, 0); rc = apply_GSUB_feature_to_glyph(hdc, psa, psc, glyphs, 0, write_dir, &glyph_count, feature); if (rc > GSUB_E_NOGLYPH) @@ -1695,7 +1696,7 @@ static void ComposeConsonants(HDC hdc, WCHAR *pwOutChars, INT *pcChars, const Co int offset = 0; int cWalk; - for (cWalk = 0; cWalk < *pcChars; cWalk++) + for (cWalk = 0; cWalk < *pcChars; cWalk += 2) { for (i = 0; consonants[i].output!= 0x0; i++) { @@ -1720,7 +1721,6 @@ static void ComposeConsonants(HDC hdc, WCHAR *pwOutChars, INT *pcChars, const Co break; } } - cWalk++; } } diff --git a/dll/win32/usp10/usp10.c b/dll/win32/usp10/usp10.c index fe83722053..ab3af43ba8 100644 --- a/dll/win32/usp10/usp10.c +++ b/dll/win32/usp10/usp10.c @@ -1373,7 +1373,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars, if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2) return E_INVALIDARG; - if (!(scripts = heap_alloc(cInChars * sizeof(*scripts)))) + if (!(scripts = heap_calloc(cInChars, sizeof(*scripts)))) return E_OUTOFMEMORY; for (i = 0; i < cInChars; i++) @@ -1464,16 +1464,13 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars, if (psState && psControl) { - levels = heap_alloc_zero(cInChars * sizeof(WORD)); - if (!levels) + if (!(levels = heap_calloc(cInChars, sizeof(*levels)))) goto nomemory; - overrides = heap_alloc_zero(cInChars * sizeof(WORD)); - if (!overrides) + if (!(overrides = heap_calloc(cInChars, sizeof(*overrides)))) goto nomemory; - layout_levels = heap_alloc_zero(cInChars * sizeof(WORD)); - if (!layout_levels) + if (!(layout_levels = heap_calloc(cInChars, sizeof(*layout_levels)))) goto nomemory; if (psState->fOverrideDirection) @@ -1519,8 +1516,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars, static const WCHAR math_punc[] = {'#','$','%','+',',','-','.','/',':',0x2212, 0x2044, 0x00a0,0}; static const WCHAR repeatable_math_punc[] = {'#','$','%','+','-','/',0x2212, 0x2044,0}; - strength = heap_alloc_zero(cInChars * sizeof(WORD)); - if (!strength) + if (!(strength = heap_calloc(cInChars, sizeof(*strength)))) goto nomemory; BIDI_GetStrengths(pwcInChars, cInChars, psControl, strength); @@ -1948,8 +1944,7 @@ static BOOL requires_fallback(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, if (SHAPE_CheckFontForRequiredFeatures(hdc, (ScriptCache *)*psc, psa) != S_OK) return TRUE; - glyphs = heap_alloc(sizeof(WORD) * cChars); - if (!glyphs) + if (!(glyphs = heap_calloc(cChars, sizeof(*glyphs)))) return FALSE; if (ScriptGetCMap(hdc, psc, pwcInChars, cChars, 0, glyphs) != S_OK) { @@ -2012,8 +2007,10 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, if (cString < 1 || !pString) return E_INVALIDARG; if ((dwFlags & SSA_GLYPHS) && !hdc) return E_PENDING; - if (!(analysis = heap_alloc_zero(sizeof(StringAnalysis)))) return E_OUTOFMEMORY; - if (!(analysis->pItem = heap_alloc_zero(num_items * sizeof(SCRIPT_ITEM) + 1))) goto error; + if (!(analysis = heap_alloc_zero(sizeof(*analysis)))) + return E_OUTOFMEMORY; + if (!(analysis->pItem = heap_calloc(num_items + 1, sizeof(*analysis->pItem)))) + goto error; /* FIXME: handle clipping */ analysis->clip_len = cString; @@ -2032,8 +2029,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, if (dwFlags & SSA_PASSWORD) { - iString = heap_alloc(sizeof(WCHAR)*cString); - if (!iString) + if (!(iString = heap_calloc(cString, sizeof(*iString)))) { hr = E_OUTOFMEMORY; goto error; @@ -2058,18 +2054,16 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, if (dwFlags & SSA_BREAK) { - if ((analysis->logattrs = heap_alloc(sizeof(SCRIPT_LOGATTR) * cString))) - { - for (i = 0; i < analysis->numItems; i++) - ScriptBreak(&((WCHAR *)pString)[analysis->pItem[i].iCharPos], - analysis->pItem[i + 1].iCharPos - analysis->pItem[i].iCharPos, - &analysis->pItem[i].a, &analysis->logattrs[analysis->pItem[i].iCharPos]); - } - else + if (!(analysis->logattrs = heap_calloc(cString, sizeof(*analysis->logattrs)))) goto error; + + for (i = 0; i < analysis->numItems; ++i) + ScriptBreak(&((const WCHAR *)pString)[analysis->pItem[i].iCharPos], + analysis->pItem[i + 1].iCharPos - analysis->pItem[i].iCharPos, + &analysis->pItem[i].a, &analysis->logattrs[analysis->pItem[i].iCharPos]); } - if (!(analysis->logical2visual = heap_alloc_zero(sizeof(int) * analysis->numItems))) + if (!(analysis->logical2visual = heap_calloc(analysis->numItems, sizeof(*analysis->logical2visual)))) goto error; if (!(BidiLevel = heap_alloc_zero(analysis->numItems))) goto error; @@ -2077,7 +2071,8 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, if (dwFlags & SSA_GLYPHS) { int tab_x = 0; - if (!(analysis->glyphs = heap_alloc_zero(sizeof(StringGlyphs) * analysis->numItems))) + + if (!(analysis->glyphs = heap_calloc(analysis->numItems, sizeof(*analysis->glyphs)))) { heap_free(BidiLevel); goto error; @@ -2088,11 +2083,11 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, SCRIPT_CACHE *sc = (SCRIPT_CACHE*)&analysis->glyphs[i].sc; int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos; int numGlyphs = 1.5 * cChar + 16; - WORD *glyphs = heap_alloc_zero(sizeof(WORD) * numGlyphs); - WORD *pwLogClust = heap_alloc_zero(sizeof(WORD) * cChar); - int *piAdvance = heap_alloc_zero(sizeof(int) * numGlyphs); - SCRIPT_VISATTR *psva = heap_alloc_zero(sizeof(SCRIPT_VISATTR) * numGlyphs); - GOFFSET *pGoffset = heap_alloc_zero(sizeof(GOFFSET) * numGlyphs); + WORD *glyphs = heap_calloc(numGlyphs, sizeof(*glyphs)); + WORD *pwLogClust = heap_calloc(cChar, sizeof(*pwLogClust)); + int *piAdvance = heap_calloc(numGlyphs, sizeof(*piAdvance)); + SCRIPT_VISATTR *psva = heap_calloc(numGlyphs, sizeof(*psva)); + GOFFSET *pGoffset = heap_calloc(numGlyphs, sizeof(*pGoffset)); int numGlyphsReturned; HFONT originalFont = 0x0; @@ -3188,8 +3183,9 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc, WCHAR *rChars; if ((hr = SHAPE_CheckFontForRequiredFeatures(hdc, (ScriptCache *)*psc, psa)) != S_OK) return hr; - rChars = heap_alloc(sizeof(WCHAR) * cChars); - if (!rChars) return E_OUTOFMEMORY; + if (!(rChars = heap_calloc(cChars, sizeof(*rChars)))) + return E_OUTOFMEMORY; + for (i = 0, g = 0, cluster = 0; i < cChars; i++) { int idx = i; @@ -3333,10 +3329,10 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, if (!psva || !pcGlyphs) return E_INVALIDARG; if (cChars > cMaxGlyphs) return E_OUTOFMEMORY; - charProps = heap_alloc_zero(sizeof(SCRIPT_CHARPROP)*cChars); - if (!charProps) return E_OUTOFMEMORY; - glyphProps = heap_alloc_zero(sizeof(SCRIPT_GLYPHPROP)*cMaxGlyphs); - if (!glyphProps) + if (!(charProps = heap_calloc(cChars, sizeof(*charProps)))) + return E_OUTOFMEMORY; + + if (!(glyphProps = heap_calloc(cMaxGlyphs, sizeof(*glyphProps)))) { heap_free(charProps); return E_OUTOFMEMORY; @@ -3501,8 +3497,8 @@ HRESULT WINAPI ScriptPlace(HDC hdc, SCRIPT_CACHE *psc, const WORD *pwGlyphs, if (!psva) return E_INVALIDARG; if (!pGoffset) return E_FAIL; - glyphProps = heap_alloc(sizeof(SCRIPT_GLYPHPROP)*cGlyphs); - if (!glyphProps) return E_OUTOFMEMORY; + if (!(glyphProps = heap_calloc(cGlyphs, sizeof(*glyphProps)))) + return E_OUTOFMEMORY; for (i = 0; i < cGlyphs; i++) glyphProps[i].sva = psva[i]; diff --git a/dll/win32/usp10/usp10_internal.h b/dll/win32/usp10/usp10_internal.h index 22295132bb..fea68918c9 100644 --- a/dll/win32/usp10/usp10_internal.h +++ b/dll/win32/usp10/usp10_internal.h @@ -154,19 +154,32 @@ typedef struct { WORD *lookups; } LoadedFeature; +enum usp10_language_table +{ + USP10_LANGUAGE_TABLE_GSUB = 0, + USP10_LANGUAGE_TABLE_GPOS, + USP10_LANGUAGE_TABLE_COUNT +}; + typedef struct { OPENTYPE_TAG tag; - const void *gsub_table; - const void *gpos_table; + const void *table[USP10_LANGUAGE_TABLE_COUNT]; BOOL features_initialized; - INT feature_count; LoadedFeature *features; + SIZE_T features_size; + SIZE_T feature_count; } LoadedLanguage; +enum usp10_script_table +{ + USP10_SCRIPT_TABLE_GSUB = 0, + USP10_SCRIPT_TABLE_GPOS, + USP10_SCRIPT_TABLE_COUNT +}; + typedef struct { OPENTYPE_TAG tag; - const void *gsub_table; - const void *gpos_table; + const void *table[USP10_SCRIPT_TABLE_COUNT]; LoadedLanguage default_language; BOOL languages_initialized; LoadedLanguage *languages; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 6ebb064c60..20f1cfb5a2 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -189,7 +189,7 @@ reactos/dll/win32/twain_32 # Synced to WineStaging-3.3 reactos/dll/win32/updspapi # Synced to WineStaging-3.3 reactos/dll/win32/url # Synced to WineStaging-3.3 reactos/dll/win32/urlmon # Synced to WineStaging-3.9 -reactos/dll/win32/usp10 # Synced to WineStaging-3.3 +reactos/dll/win32/usp10 # Synced to WineStaging-3.9 reactos/dll/win32/uxtheme # Forked reactos/dll/win32/vbscript # Synced to WineStaging-3.3 reactos/dll/win32/version # Synced to WineStaging-3.3
6 years, 6 months
1
0
0
0
01/01: [URLMON_WINETEST] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e23b04e946ae51267948d…
commit e23b04e946ae51267948d954545a30c06da50470 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:50:58 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:50:58 2018 +0100 [URLMON_WINETEST] Sync with Wine Staging 3.9. CORE-14656 --- modules/rostests/winetests/urlmon/protocol.c | 337 +++++++++++++++++++++------ modules/rostests/winetests/urlmon/url.c | 8 +- 2 files changed, 274 insertions(+), 71 deletions(-) diff --git a/modules/rostests/winetests/urlmon/protocol.c b/modules/rostests/winetests/urlmon/protocol.c index 50fe999dfe..d279694601 100644 --- a/modules/rostests/winetests/urlmon/protocol.c +++ b/modules/rostests/winetests/urlmon/protocol.c @@ -20,6 +20,7 @@ #define CONST_VTABLE #include <wine/test.h> +#include <wine/heap.h> #include <stdarg.h> #include <stdio.h> @@ -125,6 +126,8 @@ DEFINE_EXPECT(MimeFilter_Continue); DEFINE_EXPECT(Stream_Seek); DEFINE_EXPECT(Stream_Read); DEFINE_EXPECT(Redirect); +DEFINE_EXPECT(outer_QI_test); +DEFINE_EXPECT(Protocol_destructor); static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0}; static const WCHAR index_url[] = @@ -155,7 +158,7 @@ static PROTOCOLDATA protocoldata, *pdata, continue_protdata; static DWORD prot_read, filter_state, http_post_test, thread_id; static BOOL security_problem, test_async_req, impl_protex; static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort; -static BOOL empty_file, no_mime, bind_from_cache, file_with_hash; +static BOOL empty_file, no_mime, bind_from_cache, file_with_hash, reuse_protocol_thread; enum { STATE_CONNECTING, @@ -174,6 +177,17 @@ static enum { BIND_TEST } tested_protocol; +typedef struct { + IUnknown IUnknown_inner; + IInternetProtocolEx IInternetProtocolEx_iface; + IInternetPriority IInternetPriority_iface; + IUnknown *outer; + LONG inner_ref; + LONG outer_ref; +} Protocol; + +static Protocol *protocol_emul; + static const WCHAR protocol_names[][10] = { {'f','i','l','e',0}, {'h','t','t','p',0}, @@ -245,14 +259,17 @@ static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity* iface, REFGUID rgui static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem) { - trace("Security problem: %u\n", dwProblem); - ok(dwProblem == ERROR_INTERNET_SEC_CERT_REV_FAILED, "Expected ERROR_INTERNET_SEC_CERT_REV_FAILED got %u\n", dwProblem); + win_skip("Security problem: %u\n", dwProblem); + ok(dwProblem == ERROR_INTERNET_SEC_CERT_REV_FAILED || dwProblem == ERROR_INTERNET_INVALID_CA, + "Expected got %u security problem\n", dwProblem); /* Only retry once */ if (security_problem) return E_ABORT; security_problem = TRUE; + if(dwProblem == ERROR_INTERNET_INVALID_CA) + return E_ABORT; SET_EXPECT(BeginningTransaction); return RPC_E_RETRY; @@ -1156,6 +1173,9 @@ static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HR { CHECK_EXPECT(ReportResult); + if(security_problem) + return S_OK; + if(tested_protocol == FTP_TEST) ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult); else @@ -1503,6 +1523,11 @@ static IInternetBindInfoVtbl bind_info_vtbl = { static IInternetBindInfo bind_info = { &bind_info_vtbl }; +static Protocol *impl_from_IInternetPriority(IInternetPriority *iface) +{ + return CONTAINING_RECORD(iface, Protocol, IInternetPriority_iface); +} + static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv) { @@ -1512,12 +1537,16 @@ static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface, static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface) { - return 2; + Protocol *This = impl_from_IInternetPriority(iface); + This->outer_ref++; + return IUnknown_AddRef(This->outer); } static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface) { - return 1; + Protocol *This = impl_from_IInternetPriority(iface); + This->outer_ref--; + return IUnknown_Release(This->outer); } static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority) @@ -1542,8 +1571,6 @@ static const IInternetPriorityVtbl InternetPriorityVtbl = { InternetPriority_GetPriority }; -static IInternetPriority InternetPriority = { &InternetPriorityVtbl }; - static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface) { return 2; @@ -1588,83 +1615,81 @@ static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface, return E_NOTIMPL; } -static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +static Protocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface) { - static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}}; + return CONTAINING_RECORD(iface, Protocol, IInternetProtocolEx_iface); +} - if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) { - *ppv = iface; - return S_OK; - } +static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +{ + Protocol *This = impl_from_IInternetProtocolEx(iface); - if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) { - if(impl_protex) { - *ppv = iface; - return S_OK; - } - *ppv = NULL; - return E_NOINTERFACE; - } + static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}}; + static const IID unknown_iid2 = {0x5b7ebc0c,0xf630,0x4cea,{0x89,0xd3,0x5a,0xf0,0x38,0xed,0x05,0x5c}}; - if(IsEqualGUID(&IID_IInternetPriority, riid)) { - *ppv = &InternetPriority; + /* FIXME: Why is it calling here instead of outer IUnknown? */ + if(IsEqualGUID(riid, &IID_IInternetPriority)) { + *ppv = &This->IInternetPriority_iface; + IInternetPriority_AddRef(&This->IInternetPriority_iface); return S_OK; } - - if(IsEqualGUID(&IID_IWinInetInfo, riid)) { - CHECK_EXPECT(QueryInterface_IWinInetInfo); - *ppv = NULL; - return E_NOINTERFACE; - } - - if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { - CHECK_EXPECT(QueryInterface_IWinInetHttpInfo); - *ppv = NULL; - return E_NOINTERFACE; - } - - if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */ + if(!IsEqualGUID(riid, &unknown_iid) && !IsEqualGUID(riid, &unknown_iid2)) /* IE10 */ ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); *ppv = NULL; return E_NOINTERFACE; } +static ULONG WINAPI ProtocolEmul_AddRef(IInternetProtocolEx *iface) +{ + Protocol *This = impl_from_IInternetProtocolEx(iface); + This->outer_ref++; + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI ProtocolEmul_Release(IInternetProtocolEx *iface) +{ + Protocol *This = impl_from_IInternetProtocolEx(iface); + This->outer_ref--; + return IUnknown_Release(This->outer); +} + static DWORD WINAPI thread_proc(PVOID arg) { - BOOL redirect_only = redirect_on_continue; + BOOL redirect = redirect_on_continue; HRESULT hres; memset(&protocoldata, -1, sizeof(protocoldata)); - prot_state = 0; + while(1) { + prot_state = 0; - SET_EXPECT(ReportProgress_FINDINGRESOURCE); - hres = IInternetProtocolSink_ReportProgress(binding_sink, - BINDSTATUS_FINDINGRESOURCE, hostW); - CHECK_CALLED(ReportProgress_FINDINGRESOURCE); - ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); + SET_EXPECT(ReportProgress_FINDINGRESOURCE); + hres = IInternetProtocolSink_ReportProgress(binding_sink, + BINDSTATUS_FINDINGRESOURCE, hostW); + CHECK_CALLED(ReportProgress_FINDINGRESOURCE); + ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); - SET_EXPECT(ReportProgress_CONNECTING); - hres = IInternetProtocolSink_ReportProgress(binding_sink, - BINDSTATUS_CONNECTING, winehq_ipW); - CHECK_CALLED(ReportProgress_CONNECTING); - ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); + SET_EXPECT(ReportProgress_CONNECTING); + hres = IInternetProtocolSink_ReportProgress(binding_sink, + BINDSTATUS_CONNECTING, winehq_ipW); + CHECK_CALLED(ReportProgress_CONNECTING); + ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); - SET_EXPECT(ReportProgress_SENDINGREQUEST); - hres = IInternetProtocolSink_ReportProgress(binding_sink, - BINDSTATUS_SENDINGREQUEST, NULL); - CHECK_CALLED(ReportProgress_SENDINGREQUEST); - ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); + SET_EXPECT(ReportProgress_SENDINGREQUEST); + hres = IInternetProtocolSink_ReportProgress(binding_sink, + BINDSTATUS_SENDINGREQUEST, NULL); + CHECK_CALLED(ReportProgress_SENDINGREQUEST); + ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); - prot_state = 1; - SET_EXPECT(Switch); - hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata); - CHECK_CALLED(Switch); - ok(hres == S_OK, "Switch failed: %08x\n", hres); + prot_state = 1; + SET_EXPECT(Switch); + hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata); + CHECK_CALLED(Switch); + ok(hres == S_OK, "Switch failed: %08x\n", hres); - if(redirect_only) { - prot_state = 0; - return 0; + if(!redirect) + break; + redirect = FALSE; } if(!short_read) { @@ -1819,7 +1844,8 @@ static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo IServiceProvider_Release(service_provider); - CreateThread(NULL, 0, thread_proc, NULL, 0, &tid); + if(!reuse_protocol_thread) + CreateThread(NULL, 0, thread_proc, NULL, 0, &tid); return; } @@ -1929,11 +1955,13 @@ static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface, if(redirect_on_continue) { redirect_on_continue = FALSE; + reuse_protocol_thread = TRUE; if(bindinfo_options & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS) SET_EXPECT(Redirect); SET_EXPECT(ReportProgress_REDIRECTING); SET_EXPECT(Terminate); + SET_EXPECT(Protocol_destructor); SET_EXPECT(QueryService_InternetProtocol); SET_EXPECT(CreateInstance); SET_EXPECT(ReportProgress_PROTOCOLCLASSID); @@ -1945,6 +1973,7 @@ static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface, CHECK_CALLED(Redirect); CHECK_CALLED(ReportProgress_REDIRECTING); CHECK_CALLED(Terminate); + CHECK_CALLED(Protocol_destructor); CHECK_CALLED(QueryService_InternetProtocol); CHECK_CALLED(CreateInstance); CHECK_CALLED(ReportProgress_PROTOCOLCLASSID); @@ -2170,8 +2199,8 @@ static HRESULT WINAPI ProtocolEmul_StartEx(IInternetProtocolEx *iface, IUri *pUr static const IInternetProtocolExVtbl ProtocolVtbl = { ProtocolEmul_QueryInterface, - Protocol_AddRef, - Protocol_Release, + ProtocolEmul_AddRef, + ProtocolEmul_Release, ProtocolEmul_Start, ProtocolEmul_Continue, Protocol_Abort, @@ -2185,7 +2214,80 @@ static const IInternetProtocolExVtbl ProtocolVtbl = { ProtocolEmul_StartEx }; -static IInternetProtocolEx Protocol = { &ProtocolVtbl }; +static Protocol *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, Protocol, IUnknown_inner); +} + +static HRESULT WINAPI ProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + Protocol *This = impl_from_IUnknown(iface); + + if(IsEqualGUID(&IID_IUnknown, riid)) { + trace("QI(IUnknown)\n"); + *ppv = &This->IUnknown_inner; + }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) { + trace("QI(InternetProtocol)\n"); + *ppv = &This->IInternetProtocolEx_iface; + }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) { + trace("QI(InternetProtocolEx)\n"); + if(!impl_protex) { + *ppv = NULL; + return E_NOINTERFACE; + } + *ppv = &This->IInternetProtocolEx_iface; + }else if(IsEqualGUID(&IID_IInternetPriority, riid)) { + trace("QI(InternetPriority)\n"); + *ppv = &This->IInternetPriority_iface; + }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) { + trace("QI(IWinInetInfo)\n"); + CHECK_EXPECT(QueryInterface_IWinInetInfo); + *ppv = NULL; + return E_NOINTERFACE; + }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { + trace("QI(IWinInetHttpInfo)\n"); + CHECK_EXPECT(QueryInterface_IWinInetHttpInfo); + *ppv = NULL; + return E_NOINTERFACE; + }else { + ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI ProtocolUnk_AddRef(IUnknown *iface) +{ + Protocol *This = impl_from_IUnknown(iface); + return ++This->inner_ref; +} + +static ULONG WINAPI ProtocolUnk_Release(IUnknown *iface) +{ + Protocol *This = impl_from_IUnknown(iface); + LONG ref = --This->inner_ref; + if(!ref) { + /* IE9 is broken on redirects. It will cause -1 outer_ref on original protocol handler + * and 1 on redirected handler. */ + ok(!This->outer_ref + || broken(test_redirect && (This->outer_ref == -1 || This->outer_ref == 1)), + "outer_ref = %d\n", This->outer_ref); + if(This->outer_ref) + trace("outer_ref %d\n", This->outer_ref); + CHECK_EXPECT(Protocol_destructor); + heap_free(This); + } + return ref; +} + +static const IUnknownVtbl ProtocolUnkVtbl = { + ProtocolUnk_QueryInterface, + ProtocolUnk_AddRef, + ProtocolUnk_Release +}; static HRESULT WINAPI MimeProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) { @@ -2471,13 +2573,24 @@ static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **ppv) { + Protocol *ret; + CHECK_EXPECT(CreateInstance); ok(pOuter == (IUnknown*)prot_bind_info, "pOuter != protocol_unk\n"); ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid)); ok(ppv != NULL, "ppv == NULL\n"); - *ppv = &Protocol; + ret = heap_alloc(sizeof(*ret)); + ret->IUnknown_inner.lpVtbl = &ProtocolUnkVtbl; + ret->IInternetProtocolEx_iface.lpVtbl = &ProtocolVtbl; + ret->IInternetPriority_iface.lpVtbl = &InternetPriorityVtbl; + ret->outer = pOuter; + ret->inner_ref = 1; + ret->outer_ref = 0; + + protocol_emul = ret; + *ppv = &ret->IUnknown_inner; return S_OK; } @@ -2591,6 +2704,8 @@ static void init_test(int prot, DWORD flags) empty_file = (flags & TEST_EMPTY) != 0; bind_from_cache = (flags & TEST_FROMCACHE) != 0; file_with_hash = FALSE; + security_problem = FALSE; + reuse_protocol_thread = FALSE; bindinfo_options = 0; if(flags & TEST_DISABLEAUTOREDIRECT) @@ -3707,9 +3822,11 @@ static void test_CreateBinding(void) SET_EXPECT(SetPriority); SET_EXPECT(Start); + trace("Start >\n"); expect_hrResult = S_OK; hres = IInternetProtocol_Start(protocol, test_url, &protocol_sink, &bind_info, 0, 0); ok(hres == S_OK, "Start failed: %08x\n", hres); + trace("Start <\n"); CHECK_CALLED(QueryService_InternetProtocol); CHECK_CALLED(CreateInstance); @@ -3759,11 +3876,23 @@ static void test_CreateBinding(void) ok(hres == S_OK, "Terminate failed: %08x\n", hres); CHECK_CALLED(Terminate); + ok(protocol_emul->outer_ref == 0, "protocol_outer_ref = %u\n", protocol_emul->outer_ref); + SET_EXPECT(Continue); hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata); ok(hres == S_OK, "Switch failed: %08x\n", hres); CHECK_CALLED(Continue); + SET_EXPECT(Read); + read = 0xdeadbeef; + hres = IInternetProtocol_Read(protocol, expect_pv = buf, sizeof(buf), &read); + todo_wine + ok(hres == E_ABORT, "Read failed: %08x\n", hres); + todo_wine + ok(read == 0, "read = %d\n", read); + todo_wine + CHECK_NOT_CALLED(Read); + hres = IInternetProtocolSink_ReportProgress(binding_sink, BINDSTATUS_CACHEFILENAMEAVAILABLE, expect_wsz = emptyW); ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres); @@ -3777,7 +3906,10 @@ static void test_CreateBinding(void) IInternetProtocolSink_Release(binding_sink); IInternetPriority_Release(priority); IInternetBindInfo_Release(prot_bind_info); + + SET_EXPECT(Protocol_destructor); IInternetProtocol_Release(protocol); + CHECK_CALLED(Protocol_destructor); hres = IInternetSession_CreateBinding(session, NULL, test_url, NULL, NULL, &protocol, 0); ok(hres == S_OK, "CreateBinding failed: %08x\n", hres); @@ -3949,8 +4081,11 @@ static void test_binding(int prot, DWORD grf_pi, DWORD test_flags) IInternetProtocol_Release(filtered_protocol); IInternetBindInfo_Release(prot_bind_info); IInternetProtocolSink_Release(binding_sink); + + SET_EXPECT(Protocol_destructor); ref = IInternetProtocol_Release(protocol); ok(!ref, "ref=%u, expected 0\n", ref); + CHECK_CALLED(Protocol_destructor); if(test_flags & TEST_EMULATEPROT) { hres = IInternetSession_UnregisterNameSpace(session, &ClassFactory, protocol_names[prot]); @@ -3960,6 +4095,68 @@ static void test_binding(int prot, DWORD grf_pi, DWORD test_flags) IInternetSession_Release(session); } +static const IID outer_test_iid = {0xabcabc00,0,0,{0,0,0,0,0,0,0,0x66}}; + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + if(IsEqualGUID(riid, &outer_test_iid)) { + CHECK_EXPECT(outer_QI_test); + *ppv = (IUnknown*)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI outer_AddRef(IUnknown *iface) +{ + return 2; +} + +static ULONG WINAPI outer_Release(IUnknown *iface) +{ + return 1; +} + +static const IUnknownVtbl outer_vtbl = { + outer_QueryInterface, + outer_AddRef, + outer_Release +}; + +static void test_com_aggregation(const CLSID *clsid) +{ + IUnknown outer = { &outer_vtbl }; + IClassFactory *class_factory; + IUnknown *unk, *unk2, *unk3; + HRESULT hres; + + hres = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&class_factory); + ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres); + + hres = IClassFactory_CreateInstance(class_factory, &outer, &IID_IUnknown, (void**)&unk); + ok(hres == S_OK, "CreateInstance returned: %08x\n", hres); + + hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&unk2); + ok(hres == S_OK, "Could not get IDispatch iface: %08x\n", hres); + + SET_EXPECT(outer_QI_test); + hres = IUnknown_QueryInterface(unk2, &outer_test_iid, (void**)&unk3); + CHECK_CALLED(outer_QI_test); + ok(hres == S_OK, "Could not get IInternetProtocol iface: %08x\n", hres); + ok(unk3 == (IUnknown*)0xdeadbeef, "unexpected unk2\n"); + + IUnknown_Release(unk2); + IUnknown_Release(unk); + + unk = (void*)0xdeadbeef; + hres = IClassFactory_CreateInstance(class_factory, &outer, &IID_IInternetProtocol, (void**)&unk); + ok(hres == CLASS_E_NOAGGREGATION, "CreateInstance returned: %08x\n", hres); + ok(!unk, "unk = %p\n", unk); + + IClassFactory_Release(class_factory); +} + START_TEST(protocol) { HMODULE hurlmon; @@ -4033,5 +4230,11 @@ START_TEST(protocol) CloseHandle(event_continue); CloseHandle(event_continue_done); + test_com_aggregation(&CLSID_FileProtocol); + test_com_aggregation(&CLSID_HttpProtocol); + test_com_aggregation(&CLSID_HttpSProtocol); + test_com_aggregation(&CLSID_FtpProtocol); + test_com_aggregation(&CLSID_MkProtocol); + OleUninitialize(); } diff --git a/modules/rostests/winetests/urlmon/url.c b/modules/rostests/winetests/urlmon/url.c index 70234ff3fd..9fe238533a 100644 --- a/modules/rostests/winetests/urlmon/url.c +++ b/modules/rostests/winetests/urlmon/url.c @@ -160,7 +160,7 @@ static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_ static const WCHAR wszWineHQSite[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0}; static const WCHAR wszWineHQIP[] = - {'2','0','9','.','3','2','.','1','4','1','.','3',0}; + {'4','.','1','5','.','1','8','4','.','7','7',0}; static const CHAR wszIndexHtmlA[] = "index.html"; static const WCHAR cache_fileW[] = {'c',':','\\','c','a','c','h','e','.','h','t','m',0}; static const CHAR dwl_htmlA[] = "dwl.html"; @@ -2413,8 +2413,8 @@ static HRESULT WINAPI ProtocolCF_CreateInstance(IClassFactory *iface, IUnknown * if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) return E_NOINTERFACE; - todo_wine ok(outer != NULL, "outer == NULL\n"); - todo_wine ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid)); + ok(outer != NULL, "outer == NULL\n"); + ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid)); *ppv = &Protocol; return S_OK; } @@ -2902,7 +2902,7 @@ static void init_bind_test(int protocol, DWORD flags, DWORD t) url_a = "its:test.chm::/blank.html"; break; case HTTPS_TEST: - url_a = (flags & BINDTEST_INVALID_CN) ? "
https://209.46.25.134/favicon.ico
" : "
https://test.winehq.org/tests/hello.html
"; + url_a = (flags & BINDTEST_INVALID_CN) ? "
https://4.15.184.77/favicon.ico
" : "
https://test.winehq.org/tests/hello.html
"; break; case FTP_TEST: url_a = "
ftp://ftp.winehq.org/welcome.msg
";
6 years, 6 months
1
0
0
0
01/01: [URLMON] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d0eebfbd6f5cc8dd02f30…
commit d0eebfbd6f5cc8dd02f3002d85a0f1c13e9ba8a1 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:50:24 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:50:24 2018 +0100 [URLMON] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/urlmon/binding.c | 53 +++++++++---- dll/win32/urlmon/bindprot.c | 170 ++++++++++++++--------------------------- dll/win32/urlmon/file.c | 59 +++++++++++--- dll/win32/urlmon/ftp.c | 71 ++++++++++++----- dll/win32/urlmon/http.c | 80 +++++++++++++------ dll/win32/urlmon/mk.c | 73 +++++++++++++----- dll/win32/urlmon/session.c | 15 +--- dll/win32/urlmon/urlmon_main.c | 28 +++++-- dll/win32/urlmon/urlmon_main.h | 9 +-- media/doc/README.WINE | 2 +- 10 files changed, 334 insertions(+), 226 deletions(-) diff --git a/dll/win32/urlmon/binding.c b/dll/win32/urlmon/binding.c index 88b3c1cc5f..c2879b21c5 100644 --- a/dll/win32/urlmon/binding.c +++ b/dll/win32/urlmon/binding.c @@ -792,20 +792,31 @@ static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv); *ppv = &This->IServiceProvider_iface; }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) { + IWinInetInfo *wininet_info; + HRESULT hres; + TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv); /* NOTE: This violidates COM rules, but tests prove that we should do it */ - if(!This->protocol->wininet_info) - return E_NOINTERFACE; - - *ppv = &This->IWinInetHttpInfo_iface; + hres = IInternetProtocolEx_QueryInterface(&This->protocol->IInternetProtocolEx_iface, + &IID_IWinInetInfo, (void**)&wininet_info); + if(SUCCEEDED(hres)) { + IWinInetInfo_Release(wininet_info); + *ppv = &This->IWinInetHttpInfo_iface; + } }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { - TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv); + IWinInetHttpInfo *http_info; + HRESULT hres; - if(!This->protocol->wininet_http_info) - return E_NOINTERFACE; + TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv); - *ppv = &This->IWinInetHttpInfo_iface; + /* NOTE: This violidates COM rules, but tests prove that we should do it */ + hres = IInternetProtocolEx_QueryInterface(&This->protocol->IInternetProtocolEx_iface, + &IID_IWinInetHttpInfo, (void**)&http_info); + if(SUCCEEDED(hres)) { + IWinInetHttpInfo_Release(http_info); + *ppv = &This->IWinInetHttpInfo_iface; + } } if(*ppv) { @@ -1305,26 +1316,38 @@ static HRESULT WINAPI WinInetHttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD void *pBuffer, DWORD *pcbBuffer) { Binding *This = impl_from_IWinInetHttpInfo(iface); + IWinInetInfo *wininet_info; + HRESULT hres; + TRACE("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer); - if(!This->protocol->wininet_info) + hres = IInternetProtocolEx_QueryInterface(&This->protocol->IInternetProtocolEx_iface, + &IID_IWinInetInfo, (void**)&wininet_info); + if(FAILED(hres)) return E_FAIL; - return IWinInetInfo_QueryOption(This->protocol->wininet_info, - dwOption, pBuffer, pcbBuffer); + hres = IWinInetInfo_QueryOption(wininet_info, dwOption, pBuffer, pcbBuffer); + IWinInetInfo_Release(wininet_info); + return hres; } static HRESULT WINAPI WinInetHttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption, void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved) { Binding *This = impl_from_IWinInetHttpInfo(iface); + IWinInetHttpInfo *http_info; + HRESULT hres; + TRACE("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved); - if(!This->protocol->wininet_http_info) + hres = IInternetProtocolEx_QueryInterface(&This->protocol->IInternetProtocolEx_iface, + &IID_IWinInetHttpInfo, (void**)&http_info); + if(FAILED(hres)) return E_FAIL; - return IWinInetHttpInfo_QueryInfo(This->protocol->wininet_http_info, - dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved); + hres = IWinInetHttpInfo_QueryInfo(http_info, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved); + IWinInetHttpInfo_Release(http_info); + return hres; } static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = { @@ -1474,7 +1497,7 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, IUri *uri, IB ret->protocol = binding_ctx->protocol; IInternetProtocolEx_AddRef(&ret->protocol->IInternetProtocolEx_iface); }else { - hres = create_binding_protocol(TRUE, &ret->protocol); + hres = create_binding_protocol(&ret->protocol); if(FAILED(hres)) { WARN("Could not get protocol handler\n"); IBinding_Release(&ret->IBinding_iface); diff --git a/dll/win32/urlmon/bindprot.c b/dll/win32/urlmon/bindprot.c index 47c972b1e3..42d3d21925 100644 --- a/dll/win32/urlmon/bindprot.c +++ b/dll/win32/urlmon/bindprot.c @@ -283,32 +283,11 @@ static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocolEx *iface, RE }else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) { TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv); *ppv = &This->IInternetProtocolSink_iface; - }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) { - TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv); - - if(This->protocol) { - IWinInetInfo *inet_info; - HRESULT hres; - - hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetInfo, (void**)&inet_info); - if(SUCCEEDED(hres)) { - *ppv = &This->IWinInetHttpInfo_iface; - IWinInetInfo_Release(inet_info); - } - } - }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { - TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv); - - if(This->protocol) { - IWinInetHttpInfo *http_info; - HRESULT hres; - - hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetHttpInfo, (void**)&http_info); - if(SUCCEEDED(hres)) { - *ppv = &This->IWinInetHttpInfo_iface; - IWinInetHttpInfo_Release(http_info); - } - } + }else if(This->protocol_unk) { + HRESULT hres; + hres = IUnknown_QueryInterface(This->protocol_unk, riid, ppv); + TRACE("(%p) aggregated handler returned %08x for %s\n", This, hres, debugstr_guid(riid)); + return hres; }else { WARN("not supported interface %s\n", debugstr_guid(riid)); } @@ -330,14 +309,6 @@ static ULONG WINAPI BindProtocol_AddRef(IInternetProtocolEx *iface) static void release_protocol_handler(BindProtocol *This) { - if(This->wininet_info) { - IWinInetInfo_Release(This->wininet_info); - This->wininet_info = NULL; - } - if(This->wininet_http_info) { - IWinInetHttpInfo_Release(This->wininet_http_info); - This->wininet_http_info = NULL; - } if(This->protocol) { IInternetProtocol_Release(This->protocol); This->protocol = NULL; @@ -351,6 +322,10 @@ static void release_protocol_handler(BindProtocol *This) IInternetProtocolSink_Release(This->protocol_sink_handler); This->protocol_sink_handler = &This->default_protocol_handler.IInternetProtocolSink_iface; } + if(This->protocol_unk) { + IUnknown_Release(This->protocol_unk); + This->protocol_unk = NULL; + } } static ULONG WINAPI BindProtocol_Release(IInternetProtocolEx *iface) @@ -497,8 +472,8 @@ static HRESULT WINAPI BindProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr IInternetProtocolEx *protocolex; IInternetPriority *priority; IServiceProvider *service_provider; - BOOL urlmon_protocol = FALSE; CLSID clsid = IID_NULL; + IUnknown *protocol_unk = NULL; LPOLESTR clsid_str; HRESULT hres; @@ -527,28 +502,21 @@ static HRESULT WINAPI BindProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr if(!protocol) { IClassFactory *cf; - IUnknown *unk; - hres = get_protocol_handler(pUri, &clsid, &urlmon_protocol, &cf); + hres = get_protocol_handler(pUri, &clsid, &cf); if(FAILED(hres)) return hres; - if(This->from_urlmon) { - hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&protocol); - IClassFactory_Release(cf); - if(FAILED(hres)) - return hres; - }else { - hres = IClassFactory_CreateInstance(cf, (IUnknown*)&This->IInternetBindInfo_iface, - &IID_IUnknown, (void**)&unk); - IClassFactory_Release(cf); - if(FAILED(hres)) - return hres; + hres = IClassFactory_CreateInstance(cf, (IUnknown*)&This->IInternetBindInfo_iface, + &IID_IUnknown, (void**)&protocol_unk); + IClassFactory_Release(cf); + if(FAILED(hres)) + return hres; - hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&protocol); - IUnknown_Release(unk); - if(FAILED(hres)) - return hres; + hres = IUnknown_QueryInterface(protocol_unk, &IID_IInternetProtocol, (void**)&protocol); + if(FAILED(hres)) { + IUnknown_Release(protocol_unk); + return hres; } } @@ -556,22 +524,21 @@ static HRESULT WINAPI BindProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_PROTOCOLCLASSID, clsid_str); CoTaskMemFree(clsid_str); + This->protocol_unk = protocol_unk; This->protocol = protocol; - if(urlmon_protocol) { - IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&This->wininet_info); - IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&This->wininet_http_info); - } + if(!protocol_unk) + protocol_unk = (IUnknown*)protocol; set_binding_sink(This, pOIProtSink, pOIBindInfo); - hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority); + hres = IUnknown_QueryInterface(protocol_unk, &IID_IInternetPriority, (void**)&priority); if(SUCCEEDED(hres)) { IInternetPriority_SetPriority(priority, This->priority); IInternetPriority_Release(priority); } - hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex); + hres = IUnknown_QueryInterface(protocol_unk, &IID_IInternetProtocolEx, (void**)&protocolex); if(SUCCEEDED(hres)) { hres = IInternetProtocolEx_StartEx(protocolex, pUri, &This->IInternetProtocolSink_iface, &This->IInternetBindInfo_iface, 0, NULL); @@ -687,13 +654,25 @@ static HRESULT WINAPI ProtocolHandler_Start(IInternetProtocol *iface, LPCWSTR sz static HRESULT WINAPI ProtocolHandler_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) { BindProtocol *This = impl_from_IInternetProtocol(iface); + IInternetProtocol *protocol = NULL; HRESULT hres; TRACE("(%p)->(%p)\n", This, pProtocolData); - hres = IInternetProtocol_Continue(This->protocol, pProtocolData); + /* FIXME: This should not be needed. */ + if(!This->protocol) { + if(!This->protocol_unk) + return E_FAIL; + hres = IUnknown_QueryInterface(This->protocol_unk, &IID_IInternetProtocol, (void**)&protocol); + if(FAILED(hres)) + return E_FAIL; + } + + hres = IInternetProtocol_Continue(protocol ? protocol : This->protocol, pProtocolData); heap_free(pProtocolData); + if(protocol) + IInternetProtocol_Release(protocol); return hres; } @@ -722,7 +701,11 @@ static HRESULT WINAPI ProtocolHandler_Terminate(IInternetProtocol *iface, DWORD /* This may get released in Terminate call. */ IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); - IInternetProtocol_Terminate(This->protocol, 0); + if(This->protocol) { + IInternetProtocol_Terminate(This->protocol, 0); + IInternetProtocol_Release(This->protocol); + This->protocol = NULL; + } set_binding_sink(This, NULL, NULL); @@ -778,14 +761,28 @@ static HRESULT WINAPI ProtocolHandler_Read(IInternetProtocol *iface, void *pv, } if(read < cb) { + IInternetProtocol *protocol; ULONG cread = 0; + /* FIXME: We shouldn't need it, but out binding code currently depends on it. */ + if(!This->protocol && This->protocol_unk) { + hres = IUnknown_QueryInterface(This->protocol_unk, &IID_IInternetProtocol, + (void**)&protocol); + if(FAILED(hres)) + return E_ABORT; + }else { + protocol = This->protocol; + } + if(is_apartment_thread(This)) This->continue_call++; - hres = IInternetProtocol_Read(This->protocol, (BYTE*)pv+read, cb-read, &cread); + hres = IInternetProtocol_Read(protocol, (BYTE*)pv+read, cb-read, &cread); if(is_apartment_thread(This)) This->continue_call--; read += cread; + + if(!This->protocol) + IInternetProtocol_Release(protocol); } *pcbRead = read; @@ -1391,53 +1388,6 @@ static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = { BPInternetProtocolSink_ReportResult }; -static inline BindProtocol *impl_from_IWinInetHttpInfo(IWinInetHttpInfo *iface) -{ - return CONTAINING_RECORD(iface, BindProtocol, IWinInetHttpInfo_iface); -} - -static HRESULT WINAPI WinInetHttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv) -{ - BindProtocol *This = impl_from_IWinInetHttpInfo(iface); - return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv); -} - -static ULONG WINAPI WinInetHttpInfo_AddRef(IWinInetHttpInfo *iface) -{ - BindProtocol *This = impl_from_IWinInetHttpInfo(iface); - return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); -} - -static ULONG WINAPI WinInetHttpInfo_Release(IWinInetHttpInfo *iface) -{ - BindProtocol *This = impl_from_IWinInetHttpInfo(iface); - return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); -} - -static HRESULT WINAPI WinInetHttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption, - void *pBuffer, DWORD *pcbBuffer) -{ - BindProtocol *This = impl_from_IWinInetHttpInfo(iface); - FIXME("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer); - return E_NOTIMPL; -} - -static HRESULT WINAPI WinInetHttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption, - void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved) -{ - BindProtocol *This = impl_from_IWinInetHttpInfo(iface); - FIXME("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved); - return E_NOTIMPL; -} - -static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = { - WinInetHttpInfo_QueryInterface, - WinInetHttpInfo_AddRef, - WinInetHttpInfo_Release, - WinInetHttpInfo_QueryOption, - WinInetHttpInfo_QueryInfo -}; - static inline BindProtocol *impl_from_IServiceProvider(IServiceProvider *iface) { return CONTAINING_RECORD(iface, BindProtocol, IServiceProvider_iface); @@ -1482,7 +1432,7 @@ static const IServiceProviderVtbl ServiceProviderVtbl = { BPServiceProvider_QueryService }; -HRESULT create_binding_protocol(BOOL from_urlmon, BindProtocol **protocol) +HRESULT create_binding_protocol(BindProtocol **protocol) { BindProtocol *ret = heap_alloc_zero(sizeof(BindProtocol)); @@ -1491,13 +1441,11 @@ HRESULT create_binding_protocol(BOOL from_urlmon, BindProtocol **protocol) ret->IInternetPriority_iface.lpVtbl = &InternetPriorityVtbl; ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl; ret->IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkVtbl; - ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl; ret->default_protocol_handler.IInternetProtocol_iface.lpVtbl = &InternetProtocolHandlerVtbl; ret->default_protocol_handler.IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkHandlerVtbl; ret->ref = 1; - ret->from_urlmon = from_urlmon; ret->apartment_thread = GetCurrentThreadId(); ret->notif_hwnd = get_notif_hwnd(); ret->protocol_handler = &ret->default_protocol_handler.IInternetProtocol_iface; diff --git a/dll/win32/urlmon/file.c b/dll/win32/urlmon/file.c index bba7be1079..9e7f3cf184 100644 --- a/dll/win32/urlmon/file.c +++ b/dll/win32/urlmon/file.c @@ -25,9 +25,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); typedef struct { + IUnknown IUnknown_outer; IInternetProtocolEx IInternetProtocolEx_iface; IInternetPriority IInternetPriority_iface; + IUnknown *outer; + HANDLE file; ULONG size; LONG priority; @@ -35,6 +38,11 @@ typedef struct { LONG ref; } FileProtocol; +static inline FileProtocol *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, FileProtocol, IUnknown_outer); +} + static inline FileProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface) { return CONTAINING_RECORD(iface, FileProtocol, IInternetProtocolEx_iface); @@ -45,14 +53,14 @@ static inline FileProtocol *impl_from_IInternetPriority(IInternetPriority *iface return CONTAINING_RECORD(iface, FileProtocol, IInternetPriority_iface); } -static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +static HRESULT WINAPI FileProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { - FileProtocol *This = impl_from_IInternetProtocolEx(iface); + FileProtocol *This = impl_from_IUnknown(iface); *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid)) { TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); - *ppv = &This->IInternetProtocolEx_iface; + *ppv = &This->IUnknown_outer; }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv); *ppv = &This->IInternetProtocolEx_iface; @@ -68,7 +76,7 @@ static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocolEx *iface, RE } if(*ppv) { - IInternetProtocolEx_AddRef(iface); + IUnknown_AddRef((IUnknown*)*ppv); return S_OK; } @@ -76,17 +84,17 @@ static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocolEx *iface, RE return E_NOINTERFACE; } -static ULONG WINAPI FileProtocol_AddRef(IInternetProtocolEx *iface) +static ULONG WINAPI FileProtocolUnk_AddRef(IUnknown *iface) { - FileProtocol *This = impl_from_IInternetProtocolEx(iface); + FileProtocol *This = impl_from_IUnknown(iface); LONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); return ref; } -static ULONG WINAPI FileProtocol_Release(IInternetProtocolEx *iface) +static ULONG WINAPI FileProtocolUnk_Release(IUnknown *iface) { - FileProtocol *This = impl_from_IInternetProtocolEx(iface); + FileProtocol *This = impl_from_IUnknown(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); @@ -102,6 +110,33 @@ static ULONG WINAPI FileProtocol_Release(IInternetProtocolEx *iface) return ref; } +static const IUnknownVtbl FileProtocolUnkVtbl = { + FileProtocolUnk_QueryInterface, + FileProtocolUnk_AddRef, + FileProtocolUnk_Release +}; + +static HRESULT WINAPI FileProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +{ + FileProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI FileProtocol_AddRef(IInternetProtocolEx *iface) +{ + FileProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)\n", This); + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI FileProtocol_Release(IInternetProtocolEx *iface) +{ + FileProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)\n", This); + return IUnknown_Release(This->outer); +} + static HRESULT WINAPI FileProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) @@ -383,22 +418,24 @@ static const IInternetPriorityVtbl FilePriorityVtbl = { FilePriority_GetPriority }; -HRESULT FileProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) +HRESULT FileProtocol_Construct(IUnknown *outer, LPVOID *ppobj) { FileProtocol *ret; - TRACE("(%p %p)\n", pUnkOuter, ppobj); + TRACE("(%p %p)\n", outer, ppobj); URLMON_LockModule(); ret = heap_alloc(sizeof(FileProtocol)); + ret->IUnknown_outer.lpVtbl = &FileProtocolUnkVtbl; ret->IInternetProtocolEx_iface.lpVtbl = &FileProtocolExVtbl; ret->IInternetPriority_iface.lpVtbl = &FilePriorityVtbl; ret->file = INVALID_HANDLE_VALUE; ret->priority = 0; ret->ref = 1; + ret->outer = outer ? outer : (IUnknown*)&ret->IUnknown_outer; - *ppobj = &ret->IInternetProtocolEx_iface; + *ppobj = &ret->IUnknown_outer; return S_OK; } diff --git a/dll/win32/urlmon/ftp.c b/dll/win32/urlmon/ftp.c index da1efe202d..aef4a6cf16 100644 --- a/dll/win32/urlmon/ftp.c +++ b/dll/win32/urlmon/ftp.c @@ -28,13 +28,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); typedef struct { Protocol base; + IUnknown IUnknown_outer; IInternetProtocolEx IInternetProtocolEx_iface; IInternetPriority IInternetPriority_iface; IWinInetHttpInfo IWinInetHttpInfo_iface; LONG ref; + IUnknown *outer; } FtpProtocol; +static inline FtpProtocol *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, FtpProtocol, IUnknown_outer); +} + static inline FtpProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface) { return CONTAINING_RECORD(iface, FtpProtocol, IInternetProtocolEx_iface); @@ -115,14 +122,13 @@ static const ProtocolVtbl AsyncProtocolVtbl = { FtpProtocol_on_error }; -static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +static HRESULT WINAPI FtpProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { - FtpProtocol *This = impl_from_IInternetProtocolEx(iface); + FtpProtocol *This = impl_from_IUnknown(iface); - *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid)) { TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); - *ppv = &This->IInternetProtocolEx_iface; + *ppv = &This->IUnknown_outer; }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv); *ppv = &This->IInternetProtocolEx_iface; @@ -141,28 +147,27 @@ static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocolEx *iface, REF }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv); *ppv = &This->IWinInetHttpInfo_iface; + }else { + *ppv = NULL; + WARN("not supported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; } - if(*ppv) { - IInternetProtocolEx_AddRef(iface); - return S_OK; - } - - WARN("not supported interface %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; } -static ULONG WINAPI FtpProtocol_AddRef(IInternetProtocolEx *iface) +static ULONG WINAPI FtpProtocolUnk_AddRef(IUnknown *iface) { - FtpProtocol *This = impl_from_IInternetProtocolEx(iface); + FtpProtocol *This = impl_from_IUnknown(iface); LONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); return ref; } -static ULONG WINAPI FtpProtocol_Release(IInternetProtocolEx *iface) +static ULONG WINAPI FtpProtocolUnk_Release(IUnknown *iface) { - FtpProtocol *This = impl_from_IInternetProtocolEx(iface); + FtpProtocol *This = impl_from_IUnknown(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); @@ -177,6 +182,33 @@ static ULONG WINAPI FtpProtocol_Release(IInternetProtocolEx *iface) return ref; } +static const IUnknownVtbl FtpProtocolUnkVtbl = { + FtpProtocolUnk_QueryInterface, + FtpProtocolUnk_AddRef, + FtpProtocolUnk_Release +}; + +static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +{ + FtpProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI FtpProtocol_AddRef(IInternetProtocolEx *iface) +{ + FtpProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)\n", This); + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI FtpProtocol_Release(IInternetProtocolEx *iface) +{ + FtpProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)\n", This); + return IUnknown_Release(This->outer); +} + static HRESULT WINAPI FtpProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) @@ -416,23 +448,24 @@ static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = { HttpInfo_QueryInfo }; -HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) +HRESULT FtpProtocol_Construct(IUnknown *outer, void **ppv) { FtpProtocol *ret; - TRACE("(%p %p)\n", pUnkOuter, ppobj); + TRACE("(%p %p)\n", outer, ppv); URLMON_LockModule(); ret = heap_alloc_zero(sizeof(FtpProtocol)); ret->base.vtbl = &AsyncProtocolVtbl; + ret->IUnknown_outer.lpVtbl = &FtpProtocolUnkVtbl; ret->IInternetProtocolEx_iface.lpVtbl = &FtpProtocolVtbl; ret->IInternetPriority_iface.lpVtbl = &FtpPriorityVtbl; ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl; ret->ref = 1; + ret->outer = outer ? outer : &ret->IUnknown_outer; - *ppobj = &ret->IInternetProtocolEx_iface; - + *ppv = &ret->IUnknown_outer; return S_OK; } diff --git a/dll/win32/urlmon/http.c b/dll/win32/urlmon/http.c index 9cc6117aaa..5fcbd54174 100644 --- a/dll/win32/urlmon/http.c +++ b/dll/win32/urlmon/http.c @@ -32,6 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); typedef struct { Protocol base; + IUnknown IUnknown_outer; IInternetProtocolEx IInternetProtocolEx_iface; IInternetPriority IInternetPriority_iface; IWinInetHttpInfo IWinInetHttpInfo_iface; @@ -41,8 +42,14 @@ typedef struct { WCHAR *full_header; LONG ref; + IUnknown *outer; } HttpProtocol; +static inline HttpProtocol *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, HttpProtocol, IUnknown_outer); +} + static inline HttpProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface) { return CONTAINING_RECORD(iface, HttpProtocol, IInternetProtocolEx_iface); @@ -624,14 +631,13 @@ static const ProtocolVtbl AsyncProtocolVtbl = { HttpProtocol_on_error }; -static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +static HRESULT WINAPI HttpProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { - HttpProtocol *This = impl_from_IInternetProtocolEx(iface); + HttpProtocol *This = impl_from_IUnknown(iface); - *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid)) { TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); - *ppv = &This->IInternetProtocolEx_iface; + *ppv = &This->IUnknown_outer; }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv); *ppv = &This->IInternetProtocolEx_iface; @@ -650,28 +656,27 @@ static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocolEx *iface, RE }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv); *ppv = &This->IWinInetHttpInfo_iface; + }else { + *ppv = NULL; + WARN("not supported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; } - if(*ppv) { - IInternetProtocolEx_AddRef(iface); - return S_OK; - } - - WARN("not supported interface %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; } -static ULONG WINAPI HttpProtocol_AddRef(IInternetProtocolEx *iface) +static ULONG WINAPI HttpProtocolUnk_AddRef(IUnknown *iface) { - HttpProtocol *This = impl_from_IInternetProtocolEx(iface); + HttpProtocol *This = impl_from_IUnknown(iface); LONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); return ref; } -static ULONG WINAPI HttpProtocol_Release(IInternetProtocolEx *iface) +static ULONG WINAPI HttpProtocolUnk_Release(IUnknown *iface) { - HttpProtocol *This = impl_from_IInternetProtocolEx(iface); + HttpProtocol *This = impl_from_IUnknown(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); @@ -686,6 +691,33 @@ static ULONG WINAPI HttpProtocol_Release(IInternetProtocolEx *iface) return ref; } +static const IUnknownVtbl HttpProtocolUnkVtbl = { + HttpProtocolUnk_QueryInterface, + HttpProtocolUnk_AddRef, + HttpProtocolUnk_Release +}; + +static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +{ + HttpProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI HttpProtocol_AddRef(IInternetProtocolEx *iface) +{ + HttpProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)\n", This); + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI HttpProtocol_Release(IInternetProtocolEx *iface) +{ + HttpProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)\n", This); + return IUnknown_Release(This->outer); +} + static HRESULT WINAPI HttpProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) @@ -926,7 +958,7 @@ static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = { HttpInfo_QueryInfo }; -static HRESULT create_http_protocol(BOOL https, void **ppobj) +static HRESULT create_http_protocol(BOOL https, IUnknown *outer, void **ppobj) { HttpProtocol *ret; @@ -935,29 +967,31 @@ static HRESULT create_http_protocol(BOOL https, void **ppobj) return E_OUTOFMEMORY; ret->base.vtbl = &AsyncProtocolVtbl; + ret->IUnknown_outer.lpVtbl = &HttpProtocolUnkVtbl; ret->IInternetProtocolEx_iface.lpVtbl = &HttpProtocolVtbl; ret->IInternetPriority_iface.lpVtbl = &HttpPriorityVtbl; ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl; ret->https = https; ret->ref = 1; + ret->outer = outer ? outer : &ret->IUnknown_outer; - *ppobj = &ret->IInternetProtocolEx_iface; + *ppobj = &ret->IUnknown_outer; URLMON_LockModule(); return S_OK; } -HRESULT HttpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) +HRESULT HttpProtocol_Construct(IUnknown *outer, void **ppv) { - TRACE("(%p %p)\n", pUnkOuter, ppobj); + TRACE("(%p %p)\n", outer, ppv); - return create_http_protocol(FALSE, ppobj); + return create_http_protocol(FALSE, outer, ppv); } -HRESULT HttpSProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) +HRESULT HttpSProtocol_Construct(IUnknown *outer, void **ppv) { - TRACE("(%p %p)\n", pUnkOuter, ppobj); + TRACE("(%p %p)\n", outer, ppv); - return create_http_protocol(TRUE, ppobj); + return create_http_protocol(TRUE, outer, ppv); } diff --git a/dll/win32/urlmon/mk.c b/dll/win32/urlmon/mk.c index 984f381de3..d73a00c771 100644 --- a/dll/win32/urlmon/mk.c +++ b/dll/win32/urlmon/mk.c @@ -25,26 +25,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); typedef struct { + IUnknown IUnknown_outer; IInternetProtocolEx IInternetProtocolEx_iface; LONG ref; + IUnknown *outer; IStream *stream; } MkProtocol; +static inline MkProtocol *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, MkProtocol, IUnknown_outer); +} + static inline MkProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface) { return CONTAINING_RECORD(iface, MkProtocol, IInternetProtocolEx_iface); } -static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +static HRESULT WINAPI MkProtocolUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { - MkProtocol *This = impl_from_IInternetProtocolEx(iface); + MkProtocol *This = impl_from_IUnknown(iface); - *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid)) { TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); - *ppv = &This->IInternetProtocolEx_iface; + *ppv = &This->IUnknown_outer; }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv); *ppv = &This->IInternetProtocolEx_iface; @@ -54,28 +60,27 @@ static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocolEx *iface, REFI }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) { TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv); *ppv = &This->IInternetProtocolEx_iface; + }else { + *ppv = NULL; + WARN("not supported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; } - if(*ppv) { - IInternetProtocolEx_AddRef(iface); - return S_OK; - } - - WARN("not supported interface %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; } -static ULONG WINAPI MkProtocol_AddRef(IInternetProtocolEx *iface) +static ULONG WINAPI MkProtocolUnk_AddRef(IUnknown *iface) { - MkProtocol *This = impl_from_IInternetProtocolEx(iface); + MkProtocol *This = impl_from_IUnknown(iface); LONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); return ref; } -static ULONG WINAPI MkProtocol_Release(IInternetProtocolEx *iface) +static ULONG WINAPI MkProtocolUnk_Release(IUnknown *iface) { - MkProtocol *This = impl_from_IInternetProtocolEx(iface); + MkProtocol *This = impl_from_IUnknown(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); @@ -92,6 +97,33 @@ static ULONG WINAPI MkProtocol_Release(IInternetProtocolEx *iface) return ref; } +static const IUnknownVtbl MkProtocolUnkVtbl = { + MkProtocolUnk_QueryInterface, + MkProtocolUnk_AddRef, + MkProtocolUnk_Release +}; + +static HRESULT WINAPI MkProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +{ + MkProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI MkProtocol_AddRef(IInternetProtocolEx *iface) +{ + MkProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)\n", This); + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI MkProtocol_Release(IInternetProtocolEx *iface) +{ + MkProtocol *This = impl_from_IInternetProtocolEx(iface); + TRACE("(%p)\n", This); + return IUnknown_Release(This->outer); +} + static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres, DWORD dwError) { IInternetProtocolSink_ReportResult(sink, hres, dwError, NULL); @@ -330,24 +362,25 @@ static const IInternetProtocolExVtbl MkProtocolVtbl = { MkProtocol_StartEx }; -HRESULT MkProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj) +HRESULT MkProtocol_Construct(IUnknown *outer, void **ppv) { MkProtocol *ret; - TRACE("(%p %p)\n", pUnkOuter, ppobj); + TRACE("(%p %p)\n", outer, ppv); URLMON_LockModule(); ret = heap_alloc(sizeof(MkProtocol)); + ret->IUnknown_outer.lpVtbl = &MkProtocolUnkVtbl; ret->IInternetProtocolEx_iface.lpVtbl = &MkProtocolVtbl; ret->ref = 1; + ret->outer = outer ? outer : &ret->IUnknown_outer; ret->stream = NULL; /* NOTE: - * Native returns NULL ppobj and S_OK in CreateInstance if called with IID_IUnknown riid. + * Native returns NULL ppobj and S_OK in CreateInstance if called with IID_IUnknown riid and no outer. */ - *ppobj = &ret->IInternetProtocolEx_iface; - + *ppv = &ret->IUnknown_outer; return S_OK; } diff --git a/dll/win32/urlmon/session.c b/dll/win32/urlmon/session.c index 1df483f130..dea1c9f121 100644 --- a/dll/win32/urlmon/session.c +++ b/dll/win32/urlmon/session.c @@ -219,7 +219,7 @@ IInternetProtocolInfo *get_protocol_info(LPCWSTR url) return ret; } -HRESULT get_protocol_handler(IUri *uri, CLSID *clsid, BOOL *urlmon_protocol, IClassFactory **ret) +HRESULT get_protocol_handler(IUri *uri, CLSID *clsid, IClassFactory **ret) { name_space *ns; BSTR scheme; @@ -240,20 +240,11 @@ HRESULT get_protocol_handler(IUri *uri, CLSID *clsid, BOOL *urlmon_protocol, ICl IClassFactory_AddRef(*ret); if(clsid) *clsid = ns->clsid; - if(urlmon_protocol) - *urlmon_protocol = ns->urlmon; } LeaveCriticalSection(&session_cs); - if(*ret) { - hres = S_OK; - }else { - if(urlmon_protocol) - *urlmon_protocol = FALSE; - hres = get_protocol_cf(scheme, SysStringLen(scheme), clsid, ret); - } - + hres = *ret ? S_OK : get_protocol_cf(scheme, SysStringLen(scheme), clsid, ret); SysFreeString(scheme); return hres; } @@ -448,7 +439,7 @@ static HRESULT WINAPI InternetSession_CreateBinding(IInternetSession *iface, if(pBC || pUnkOuter || ppUnk || dwOption) FIXME("Unsupported arguments\n"); - hres = create_binding_protocol(FALSE, &protocol); + hres = create_binding_protocol(&protocol); if(FAILED(hres)) return hres; diff --git a/dll/win32/urlmon/urlmon_main.c b/dll/win32/urlmon/urlmon_main.c index c4f1cec5fa..5968a6ce55 100644 --- a/dll/win32/urlmon/urlmon_main.c +++ b/dll/win32/urlmon/urlmon_main.c @@ -303,19 +303,31 @@ static ULONG WINAPI CF_Release(IClassFactory *iface) } -static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, - REFIID riid, LPVOID *ppobj) +static HRESULT WINAPI CF_CreateInstance(IClassFactory *iface, IUnknown *outer, + REFIID riid, void **ppv) { ClassFactory *This = impl_from_IClassFactory(iface); + IUnknown *unk; HRESULT hres; - LPUNKNOWN punk; - TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); + TRACE("(%p)->(%p %s %p)\n", This, outer, debugstr_guid(riid), ppv); - *ppobj = NULL; - if(SUCCEEDED(hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk))) { - hres = IUnknown_QueryInterface(punk, riid, ppobj); - IUnknown_Release(punk); + if(outer && !IsEqualGUID(riid, &IID_IUnknown)) { + *ppv = NULL; + return CLASS_E_NOAGGREGATION; + } + + hres = This->pfnCreateInstance(outer, (void**)&unk); + if(FAILED(hres)) { + *ppv = NULL; + return hres; + } + + if(!IsEqualGUID(riid, &IID_IUnknown)) { + hres = IUnknown_QueryInterface(unk, riid, ppv); + IUnknown_Release(unk); + }else { + *ppv = unk; } return hres; } diff --git a/dll/win32/urlmon/urlmon_main.h b/dll/win32/urlmon/urlmon_main.h index a4a1c78d52..39dbe2f572 100644 --- a/dll/win32/urlmon/urlmon_main.h +++ b/dll/win32/urlmon/urlmon_main.h @@ -66,7 +66,7 @@ static inline void URLMON_UnlockModule(void) { InterlockedDecrement( &URLMON_ref extern HINSTANCE urlmon_instance; IInternetProtocolInfo *get_protocol_info(LPCWSTR) DECLSPEC_HIDDEN; -HRESULT get_protocol_handler(IUri*,CLSID*,BOOL*,IClassFactory**) DECLSPEC_HIDDEN; +HRESULT get_protocol_handler(IUri*,CLSID*,IClassFactory**) DECLSPEC_HIDDEN; IInternetProtocol *get_mime_filter(LPCWSTR) DECLSPEC_HIDDEN; BOOL is_registered_protocol(LPCWSTR) DECLSPEC_HIDDEN; HRESULT register_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL) DECLSPEC_HIDDEN; @@ -172,13 +172,11 @@ typedef struct { IInternetPriority IInternetPriority_iface; IServiceProvider IServiceProvider_iface; IInternetProtocolSink IInternetProtocolSink_iface; - IWinInetHttpInfo IWinInetHttpInfo_iface; LONG ref; + IUnknown *protocol_unk; IInternetProtocol *protocol; - IWinInetInfo *wininet_info; - IWinInetHttpInfo *wininet_http_info; IInternetBindInfo *bind_info; IInternetProtocolSink *protocol_sink; @@ -196,7 +194,6 @@ typedef struct { BOOL reported_result; BOOL reported_mime; - BOOL from_urlmon; DWORD pi; DWORD bscf; @@ -217,7 +214,7 @@ typedef struct { BSTR display_uri; } BindProtocol; -HRESULT create_binding_protocol(BOOL,BindProtocol**) DECLSPEC_HIDDEN; +HRESULT create_binding_protocol(BindProtocol**) DECLSPEC_HIDDEN; void set_binding_sink(BindProtocol*,IInternetProtocolSink*,IInternetBindInfo*) DECLSPEC_HIDDEN; typedef struct { diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 32a8639dc3..6ebb064c60 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -188,7 +188,7 @@ reactos/dll/win32/traffic # Synced to WineStaging-3.3 reactos/dll/win32/twain_32 # Synced to WineStaging-3.3 reactos/dll/win32/updspapi # Synced to WineStaging-3.3 reactos/dll/win32/url # Synced to WineStaging-3.3 -reactos/dll/win32/urlmon # Synced to WineStaging-3.3 +reactos/dll/win32/urlmon # Synced to WineStaging-3.9 reactos/dll/win32/usp10 # Synced to WineStaging-3.3 reactos/dll/win32/uxtheme # Forked reactos/dll/win32/vbscript # Synced to WineStaging-3.3
6 years, 6 months
1
0
0
0
01/01: [RPCRT4_WINETEST] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dfaac82a1c6f27405b24e…
commit dfaac82a1c6f27405b24ecf399bcee74eac2d768 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:49:34 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:49:34 2018 +0100 [RPCRT4_WINETEST] Sync with Wine Staging 3.9. CORE-14656 --- modules/rostests/winetests/rpcrt4/server.c | 62 ++++++++++++++++++++++++++++ modules/rostests/winetests/rpcrt4/server.idl | 10 +++++ 2 files changed, 72 insertions(+) diff --git a/modules/rostests/winetests/rpcrt4/server.c b/modules/rostests/winetests/rpcrt4/server.c index c976709c1c..96cea2c3f6 100644 --- a/modules/rostests/winetests/rpcrt4/server.c +++ b/modules/rostests/winetests/rpcrt4/server.c @@ -844,6 +844,23 @@ void __cdecl s_stop(void) } } +void __cdecl s_stop_autolisten(void) +{ + RPC_STATUS status; + status = RpcServerUnregisterIf(NULL, NULL, FALSE); +todo_wine + ok(status == RPC_S_UNKNOWN_MGR_TYPE, "got %u\n", status); +} + +void __cdecl s_ip_test(ipu_t *a) +{ + STATSTG st; + HRESULT hr; + + hr = IStream_Stat(a->tagged_union.stream, &st, STATFLAG_NONAME); + ok(hr == S_OK, "got %#x\n", hr); +} + static void make_cmdline(char buffer[MAX_PATH], const char *test) { @@ -1044,6 +1061,8 @@ union_tests(void) encu_t eu; unencu_t uneu; sun_t su; + ipu_t ipu; + LONG ref; int i; su.s = SUN_I; @@ -1084,6 +1103,15 @@ union_tests(void) eue.t = E2; eue.tagged_union.f2 = 10.0; ok(square_encue(&eue) == 100.0, "RPC square_encue\n"); + + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + CreateStreamOnHGlobal(NULL, TRUE, &ipu.tagged_union.stream); + ip_test(&ipu); + ref = IStream_Release(ipu.tagged_union.stream); + ok(!ref, "got %u refs\n", ref); + + CoUninitialize(); } static test_list_t * @@ -1660,6 +1688,22 @@ client(const char *test) ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n"); } + else if (strcmp(test, "ncalrpc_autolisten") == 0) + { + ok(RPC_S_OK == RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding), "RpcStringBindingCompose\n"); + ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n"); + + run_tests(); + authinfo_test(RPC_PROTSEQ_LRPC, 0); +todo_wine + test_is_server_listening(IServer_IfHandle, RPC_S_NOT_LISTENING); + + stop_autolisten(); + ok(int_return() == INT_CODE, "RPC int_return\n"); + + ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); + ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n"); + } else if (strcmp(test, "ncalrpc_secure") == 0) { ok(RPC_S_OK == RpcStringBindingComposeA(NULL, ncalrpc, NULL, guid, NULL, &binding), "RpcStringBindingCompose\n"); @@ -1701,6 +1745,9 @@ server(void) RPC_STATUS status, iptcp_status, np_status, ncalrpc_status; DWORD ret; + /* needed for tests involving interface pointers */ + CoInitializeEx(NULL, COINIT_MULTITHREADED); + iptcp_status = RpcServerUseProtseqEpA(iptcp, 20, port, NULL); ok(iptcp_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_ip_tcp) failed with status %d\n", iptcp_status); @@ -1766,6 +1813,21 @@ server(void) CloseHandle(stop_event); stop_event = NULL; + + if (pRpcServerRegisterIfEx) + { + status = pRpcServerRegisterIfEx(s_IServer_v0_0_s_ifspec, NULL, NULL, + RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH | RPC_IF_AUTOLISTEN, + RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL); + ok(status == RPC_S_OK, "RpcServerRegisterIf() failed: %u\n", status); + + run_client("ncalrpc_autolisten"); + + status = RpcServerUnregisterIf(s_IServer_v0_0_s_ifspec, NULL, TRUE); + ok(status == RPC_S_OK, "RpcServerUnregisterIf() failed: %u\n", status); + } + + CoUninitialize(); } static DWORD WINAPI listen_test_client_thread(void *binding) diff --git a/modules/rostests/winetests/rpcrt4/server.idl b/modules/rostests/winetests/rpcrt4/server.idl index 8a02c29e23..6aa73823f0 100644 --- a/modules/rostests/winetests/rpcrt4/server.idl +++ b/modules/rostests/winetests/rpcrt4/server.idl @@ -21,6 +21,8 @@ #pragma makedep client #pragma makedep server +import "objidl.idl"; + #include "server_defines.h" typedef struct tag_vector @@ -383,4 +385,12 @@ cpp_quote("#endif") void authinfo_test(unsigned int protseq, int secure); void stop(void); + void stop_autolisten(void); + + typedef union ipu switch(int t) + { + default: IStream *stream; + } ipu_t; + + void ip_test([in] ipu_t *a); }
6 years, 6 months
1
0
0
0
01/01: [RPCRT4] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=96d77d846fc22468b7fdc…
commit 96d77d846fc22468b7fdc00720ded699a641e508 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:49:11 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:49:11 2018 +0100 [RPCRT4] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/rpcrt4/ndr_marshall.c | 28 ++++++++++++++++++++++++---- dll/win32/rpcrt4/rpc_server.c | 3 ++- media/doc/README.WINE | 2 +- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/dll/win32/rpcrt4/ndr_marshall.c b/dll/win32/rpcrt4/ndr_marshall.c index ee58b60a55..6356fb9d98 100644 --- a/dll/win32/rpcrt4/ndr_marshall.c +++ b/dll/win32/rpcrt4/ndr_marshall.c @@ -5745,11 +5745,16 @@ static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned c pStubMsg->Buffer = saved_buffer + 4; } break; + case RPC_FC_IP: + /* must be dereferenced first */ + m(pStubMsg, *(unsigned char **)pMemory, desc); + break; default: m(pStubMsg, pMemory, desc); } } - else FIXME("no marshaller for embedded type %02x\n", *desc); + else if (*desc) + FIXME("no marshaller for embedded type %02x\n", *desc); } return NULL; } @@ -5814,11 +5819,16 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->Buffer = saved_buffer + 4; } break; + case RPC_FC_IP: + /* must be dereferenced first */ + m(pStubMsg, *(unsigned char ***)ppMemory, desc, fMustAlloc); + break; default: m(pStubMsg, ppMemory, desc, fMustAlloc); } } - else FIXME("no marshaller for embedded type %02x\n", *desc); + else if (*desc) + FIXME("no marshaller for embedded type %02x\n", *desc); } return NULL; } @@ -5868,11 +5878,16 @@ static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->BufferLength = saved_buffer_length; } break; + case RPC_FC_IP: + /* must be dereferenced first */ + m(pStubMsg, *(unsigned char **)pMemory, desc); + break; default: m(pStubMsg, pMemory, desc); } } - else FIXME("no buffersizer for embedded type %02x\n", *desc); + else if (*desc) + FIXME("no buffersizer for embedded type %02x\n", *desc); } } @@ -5920,7 +5935,8 @@ static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg, return m(pStubMsg, desc); } } - else FIXME("no marshaller for embedded type %02x\n", *desc); + else if (*desc) + FIXME("no marshaller for embedded type %02x\n", *desc); } TRACE("size %d\n", size); @@ -5955,6 +5971,10 @@ static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_FP: PointerFree(pStubMsg, *(unsigned char **)pMemory, desc); break; + case RPC_FC_IP: + /* must be dereferenced first */ + m(pStubMsg, *(unsigned char **)pMemory, desc); + break; default: m(pStubMsg, pMemory, desc); } diff --git a/dll/win32/rpcrt4/rpc_server.c b/dll/win32/rpcrt4/rpc_server.c index d1b5d64ece..91de3b95fa 100644 --- a/dll/win32/rpcrt4/rpc_server.c +++ b/dll/win32/rpcrt4/rpc_server.c @@ -1220,7 +1220,8 @@ RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid EnterCriticalSection(&server_cs); LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) { - if ((!IfSpec || !memcmp(&If->InterfaceId, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER))) && + if (((!IfSpec && !(cif->Flags & RPC_IF_AUTOLISTEN)) || + (IfSpec && !memcmp(&If->InterfaceId, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)))) && UuidEqual(MgrTypeUuid, &cif->MgrTypeUuid, &status)) { list_remove(&cif->entry); TRACE("unregistering cif %p\n", cif); diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 4e58c6349f..32a8639dc3 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -160,7 +160,7 @@ reactos/dll/win32/rasapi32 # Synced to WineStaging-3.3 reactos/dll/win32/resutils # Synced to WineStaging-3.3 reactos/dll/win32/riched20 # Synced to WineStaging-3.9 reactos/dll/win32/riched32 # Synced to WineStaging-3.3 -reactos/dll/win32/rpcrt4 # Synced to WineStaging-3.3 +reactos/dll/win32/rpcrt4 # Synced to WineStaging-3.9 reactos/dll/win32/rsabase # Synced to WineStaging-3.3 reactos/dll/win32/rsaenh # Synced to WineStaging-2.9 reactos/dll/win32/sccbase # Synced to WineStaging-3.3
6 years, 6 months
1
0
0
0
01/01: [RICHED20_WINETEST] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9e90c368efba5deba548f…
commit 9e90c368efba5deba548ffece95daeff5833a9d0 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:48:31 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:48:31 2018 +0100 [RICHED20_WINETEST] Sync with Wine Staging 3.9. CORE-14656 --- modules/rostests/winetests/riched20/editor.c | 92 +++++++ modules/rostests/winetests/riched20/richole.c | 357 ++++++++++++++++++++++---- modules/rostests/winetests/riched20/txtsrv.c | 1 + 3 files changed, 401 insertions(+), 49 deletions(-) diff --git a/modules/rostests/winetests/riched20/editor.c b/modules/rostests/winetests/riched20/editor.c index 0e0c960ba2..6712ab1a15 100644 --- a/modules/rostests/winetests/riched20/editor.c +++ b/modules/rostests/winetests/riched20/editor.c @@ -20,6 +20,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + #include <stdarg.h> #include <stdio.h> #include <assert.h> @@ -30,6 +32,7 @@ #include <winnls.h> #include <ole2.h> #include <richedit.h> +#include <richole.h> #include <commdlg.h> #include <time.h> #include <wine/test.h> @@ -8798,6 +8801,94 @@ static void test_para_numbering(void) DestroyWindow( edit ); } +static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj, + LPSTORAGE pstg, LPOLECLIENTSITE polesite, LONG sizel_cx, + LONG sizel_cy, DWORD aspect, DWORD flags, DWORD user) +{ + reobj->cbStruct = sizeof(*reobj); + reobj->clsid = CLSID_NULL; + reobj->cp = cp; + reobj->poleobj = poleobj; + reobj->pstg = pstg; + reobj->polesite = polesite; + reobj->sizel.cx = sizel_cx; + reobj->sizel.cy = sizel_cy; + reobj->dvaspect = aspect; + reobj->dwFlags = flags; + reobj->dwUser = user; +} + +static void test_EM_SELECTIONTYPE(void) +{ + HWND hwnd = new_richedit(NULL); + IRichEditOle *reole = NULL; + static const char text1[] = "abcdefg\n"; + int result; + REOBJECT reo1, reo2; + IOleClientSite *clientsite; + HRESULT hr; + + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)text1); + SendMessageA(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&reole); + + SendMessageA(hwnd, EM_SETSEL, 1, 1); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == SEL_EMPTY, "got wrong selection type: %x.\n", result); + + SendMessageA(hwnd, EM_SETSEL, 1, 2); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == SEL_TEXT, "got wrong selection type: %x.\n", result); + + SendMessageA(hwnd, EM_SETSEL, 2, 5); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == (SEL_TEXT | SEL_MULTICHAR), "got wrong selection type: %x.\n", result); + + SendMessageA(hwnd, EM_SETSEL, 0, 1); + hr = IRichEditOle_GetClientSite(reole, &clientsite); + ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr); + fill_reobject_struct(&reo1, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, + DVASPECT_CONTENT, 0, 1); + hr = IRichEditOle_InsertObject(reole, &reo1); + ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr); + IOleClientSite_Release(clientsite); + + SendMessageA(hwnd, EM_SETSEL, 0, 1); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == SEL_OBJECT, "got wrong selection type: %x.\n", result); + + SendMessageA(hwnd, EM_SETSEL, 0, 2); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == (SEL_TEXT | SEL_OBJECT), "got wrong selection type: %x.\n", result); + + SendMessageA(hwnd, EM_SETSEL, 0, 3); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT), "got wrong selection type: %x.\n", result); + + SendMessageA(hwnd, EM_SETSEL, 2, 3); + hr = IRichEditOle_GetClientSite(reole, &clientsite); + ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr); + fill_reobject_struct(&reo2, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, + DVASPECT_CONTENT, 0, 2); + hr = IRichEditOle_InsertObject(reole, &reo2); + ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr); + IOleClientSite_Release(clientsite); + + SendMessageA(hwnd, EM_SETSEL, 0, 2); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == (SEL_OBJECT | SEL_TEXT), "got wrong selection type: %x.\n", result); + + SendMessageA(hwnd, EM_SETSEL, 0, 3); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == (SEL_OBJECT | SEL_MULTIOBJECT | SEL_TEXT), "got wrong selection type: %x.\n", result); + + SendMessageA(hwnd, EM_SETSEL, 0, 4); + result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0); + ok(result == (SEL_TEXT| SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT), "got wrong selection type: %x.\n", result); + + IRichEditOle_Release(reole); + DestroyWindow(hwnd); +} + static void test_window_classes(void) { static const struct @@ -8905,6 +8996,7 @@ START_TEST( editor ) test_background(); test_eop_char_fmt(); test_para_numbering(); + test_EM_SELECTIONTYPE(); /* Set the environment variable WINETEST_RICHED20 to keep windows * responsive and open for 30 seconds. This is useful for debugging. diff --git a/modules/rostests/winetests/riched20/richole.c b/modules/rostests/winetests/riched20/richole.c index 3a69819630..617d1f978b 100644 --- a/modules/rostests/winetests/riched20/richole.c +++ b/modules/rostests/winetests/riched20/richole.c @@ -3132,39 +3132,152 @@ static void test_SetFont(void) ITextSelection_Release(selection); } +static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj, + LPSTORAGE pstg, LPOLECLIENTSITE polesite, LONG sizel_cx, + LONG sizel_cy, DWORD aspect, DWORD flags, DWORD user) +{ + reobj->cbStruct = sizeof(*reobj); + reobj->clsid = CLSID_NULL; + reobj->cp = cp; + reobj->poleobj = poleobj; + reobj->pstg = pstg; + reobj->polesite = polesite; + reobj->sizel.cx = sizel_cx; + reobj->sizel.cy = sizel_cy; + reobj->dvaspect = aspect; + reobj->dwFlags = flags; + reobj->dwUser = user; +} + +#define CHECK_REOBJECT_STRUCT(reobj,poleobj,pstg,polesite,user) \ + _check_reobject_struct(reobj, poleobj, pstg, polesite, user, __LINE__) +static void _check_reobject_struct(REOBJECT reobj, LPOLEOBJECT poleobj, LPSTORAGE pstg, + LPOLECLIENTSITE polesite, DWORD user, int line) +{ + ok_(__FILE__,line)(reobj.poleobj == poleobj, "got wrong object interface.\n"); + ok_(__FILE__,line)(reobj.pstg == pstg, "got wrong storage interface.\n"); + ok_(__FILE__,line)(reobj.polesite == polesite, "got wrong site interface.\n"); + ok_(__FILE__,line)(reobj.dwUser == user, "got wrong user-defined value.\n"); +} + static void test_InsertObject(void) { + static CHAR test_text1[] = "abcdefg"; IRichEditOle *reole = NULL; ITextDocument *doc = NULL; IOleClientSite *clientsite; - REOBJECT reo; + REOBJECT reo1, reo2, reo3, received_reo1, received_reo2, received_reo3, received_reo4; HRESULT hr; HWND hwnd; + LONG count; create_interfaces(&hwnd, &reole, &doc, NULL); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); hr = IRichEditOle_InsertObject(reole, NULL); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + /* insert object1 in (0, 1)*/ + SendMessageA(hwnd, EM_SETSEL, 0, 1); hr = IRichEditOle_GetClientSite(reole, &clientsite); - ok(hr == S_OK, "got 0x%08x\n", hr); - - reo.cbStruct = sizeof(reo); - reo.cp = 0; - memset(&reo.clsid, 0, sizeof(reo.clsid)); - reo.poleobj = NULL; - reo.pstg = NULL; - reo.polesite = clientsite; - reo.sizel.cx = 10; - reo.sizel.cy = 10; - reo.dvaspect = DVASPECT_CONTENT; - reo.dwFlags = 0; - reo.dwUser = 0; + ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr); + fill_reobject_struct(&reo1, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 1); + hr = IRichEditOle_InsertObject(reole, &reo1); + ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr); + count = IRichEditOle_GetObjectCount(reole); + ok(count == 1, "got wrong object count: %d\n", count); + IOleClientSite_Release(clientsite); - hr = IRichEditOle_InsertObject(reole, &reo); - ok(hr == S_OK, "got 0x%08x\n", hr); + /* insert object2 in (2, 3)*/ + SendMessageA(hwnd, EM_SETSEL, 2, 3); + hr = IRichEditOle_GetClientSite(reole, &clientsite); + ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr); + fill_reobject_struct(&reo2, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 2); + hr = IRichEditOle_InsertObject(reole, &reo2); + ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr); + count = IRichEditOle_GetObjectCount(reole); + ok(count == 2, "got wrong object count: %d\n", count); + IOleClientSite_Release(clientsite); + /* insert object3 in (1, 2)*/ + SendMessageA(hwnd, EM_SETSEL, 1, 2); + hr = IRichEditOle_GetClientSite(reole, &clientsite); + ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr); + fill_reobject_struct(&reo3, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0, 3); + hr = IRichEditOle_InsertObject(reole, &reo3); + ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr); + count = IRichEditOle_GetObjectCount(reole); + ok(count == 3, "got wrong object count: %d\n", count); IOleClientSite_Release(clientsite); + + /* tests below show that order of rebject (from 0 to 2) is: reo1,reo3,reo2 */ + received_reo1.cbStruct = sizeof(received_reo1); + hr = IRichEditOle_GetObject(reole, 0, &received_reo1, REO_GETOBJ_ALL_INTERFACES); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo1, NULL, NULL, reo1.polesite, 1); + + received_reo2.cbStruct = sizeof(received_reo2); + hr = IRichEditOle_GetObject(reole, 1, &received_reo2, REO_GETOBJ_ALL_INTERFACES); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo2, NULL, NULL, reo3.polesite, 3); + + received_reo3.cbStruct = sizeof(received_reo3); + hr = IRichEditOle_GetObject(reole, 2, &received_reo3, REO_GETOBJ_ALL_INTERFACES); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo3, NULL, NULL, reo2.polesite, 2); + + hr = IRichEditOle_GetObject(reole, 2, NULL, REO_GETOBJ_ALL_INTERFACES); + ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); + + received_reo4.cbStruct = 0; + hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); + + received_reo4.cbStruct = sizeof(received_reo4); + hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_PSTG); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2); + + hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_POLESITE); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2); + + hr = IRichEditOle_GetObject(reole, 4, &received_reo4, REO_GETOBJ_POLESITE); + ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); + + hr = IRichEditOle_GetObject(reole, 1024, &received_reo4, REO_GETOBJ_POLESITE); + ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); + + /* received_reo4 will be zeroed before be used */ + hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_NO_INTERFACES); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2); + + received_reo4.cbStruct = sizeof(received_reo4); + received_reo4.cp = 0; + hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1); + + received_reo4.cbStruct = sizeof(received_reo4); + received_reo4.cp = 1; + hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3); + + received_reo4.cbStruct = sizeof(received_reo4); + received_reo4.cp = 2; + hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr); + CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2); + + received_reo4.cbStruct = sizeof(received_reo4); + received_reo4.cp = 4; + hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4, REO_GETOBJ_ALL_INTERFACES); + ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr); + /* received_reo4 didn't be zeroed in E_INVALIDARG case */ + CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2); + release_interfaces(&hwnd, &reole, &doc, NULL); } @@ -3310,6 +3423,64 @@ static void test_ITextSelection_GetDuplicate(void) ITextRange_Release(range); } +#define RESET_RANGE(range,start,end) \ + _reset_range(range, start, end, __LINE__) +static void _reset_range(ITextRange *range, LONG start, LONG end, int line) +{ + HRESULT hr; + + hr = ITextRange_SetStart(range, start); + ok_(__FILE__,line)(hr == S_OK, "SetStart failed: 0x%08x\n", hr); + hr = ITextRange_SetEnd(range, end); + ok_(__FILE__,line)(hr == S_OK, "SetEnd failed: 0x%08x\n", hr); +} + +#define CHECK_RANGE(range,expected_start,expected_end) \ + _check_range(range, expected_start, expected_end, __LINE__) +static void _check_range(ITextRange* range, LONG expected_start, LONG expected_end, int line) +{ + HRESULT hr; + LONG value; + + hr = ITextRange_GetStart(range, &value); + ok_(__FILE__,line)(hr == S_OK, "GetStart failed: 0x%08x\n", hr); + ok_(__FILE__,line)(value == expected_start, "Expected start %d got %d\n", + expected_start, value); + hr = ITextRange_GetEnd(range, &value); + ok_(__FILE__,line)(hr == S_OK, "GetEnd failed: 0x%08x\n", hr); + ok_(__FILE__,line)(value == expected_end, "Expected end %d got %d\n", + expected_end, value); +} + +#define RESET_SELECTION(selection,start,end) \ + _reset_selection(selection, start, end, __LINE__) +static void _reset_selection(ITextSelection *selection, LONG start, LONG end, int line) +{ + HRESULT hr; + + hr = ITextSelection_SetStart(selection, start); + ok_(__FILE__,line)(hr == S_OK, "SetStart failed: 0x%08x\n", hr); + hr = ITextSelection_SetEnd(selection, end); + ok_(__FILE__,line)(hr == S_OK, "SetEnd failed: 0x%08x\n", hr); +} + +#define CHECK_SELECTION(selection,expected_start,expected_end) \ + _check_selection(selection, expected_start, expected_end, __LINE__) +static void _check_selection(ITextSelection *selection, LONG expected_start, LONG expected_end, int line) +{ + HRESULT hr; + LONG value; + + hr = ITextSelection_GetStart(selection, &value); + ok_(__FILE__,line)(hr == S_OK, "GetStart failed: 0x%08x\n", hr); + ok_(__FILE__,line)(value == expected_start, "Expected start %d got %d\n", + expected_start, value); + hr = ITextSelection_GetEnd(selection, &value); + ok_(__FILE__,line)(hr == S_OK, "GetEnd failed: 0x%08x\n", hr); + ok_(__FILE__,line)(value == expected_end, "Expected end %d got %d\n", + expected_end, value); +} + static void test_Expand(void) { static const char test_text1[] = "TestSomeText"; @@ -3330,53 +3501,26 @@ static void test_Expand(void) hr = ITextRange_Expand(range, tomStory, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); - hr = ITextRange_GetStart(range, &value); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(value == 0, "got %d\n", value); - hr = ITextRange_GetEnd(range, &value); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(value == 13, "got %d\n", value); + CHECK_RANGE(range, 0, 13); hr = ITextSelection_Expand(selection, tomStory, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); - hr = ITextSelection_GetStart(selection, &value); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(value == 0, "got %d\n", value); - hr = ITextSelection_GetEnd(selection, &value); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(value == 13, "got %d\n", value); + CHECK_SELECTION(selection, 0, 13); - hr = ITextRange_SetStart(range, 1); - ok(hr == S_OK, "got 0x%08x\n", hr); - hr = ITextRange_SetEnd(range, 2); - ok(hr == S_OK, "got 0x%08x\n", hr); - - hr = ITextSelection_SetStart(selection, 1); - ok(hr == S_OK, "got 0x%08x\n", hr); - hr = ITextSelection_SetEnd(selection, 2); - ok(hr == S_OK, "got 0x%08x\n", hr); + RESET_RANGE(range, 1, 2); + RESET_SELECTION(selection, 1, 2); value = 0; hr = ITextRange_Expand(range, tomStory, &value); ok(hr == S_OK, "got 0x%08x\n", hr); ok(value == 12, "got %d\n", value); - hr = ITextRange_GetStart(range, &value); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(value == 0, "got %d\n", value); - hr = ITextRange_GetEnd(range, &value); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(value == 13, "got %d\n", value); + CHECK_RANGE(range, 0, 13); value = 0; hr = ITextSelection_Expand(selection, tomStory, &value); ok(hr == S_OK, "got 0x%08x\n", hr); ok(value == 12, "got %d\n", value); - hr = ITextSelection_GetStart(selection, &value); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(value == 0, "got %d\n", value); - hr = ITextSelection_GetEnd(selection, &value); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(value == 13, "got %d\n", value); + CHECK_SELECTION(selection, 0, 13); release_interfaces(&hwnd, &reole, &doc, NULL); @@ -3396,6 +3540,120 @@ static void test_Expand(void) ITextRange_Release(range); } +static void test_MoveEnd(void) +{ + static const char test_text1[] = "Word1 Word2"; + IRichEditOle *reole = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + ITextRange *range; + LONG delta; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reole, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextDocument_Range(doc, 1, 2, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_MoveEnd(range, tomStory, 0, &delta); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(delta == 0, "got %d\n", delta); + CHECK_RANGE(range, 1, 2); + + hr = ITextRange_MoveEnd(range, tomStory, -1, &delta); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(delta == -1, "got %d\n", delta); + CHECK_RANGE(range, 0, 0); + + hr = ITextRange_MoveEnd(range, tomStory, 1, &delta); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(delta == 1, "got %d\n", delta); + CHECK_RANGE(range, 0, 12); + + hr = ITextRange_MoveEnd(range, tomStory, 1, &delta); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(delta == 0, "got %d\n", delta); + CHECK_RANGE(range, 0, 12); + + RESET_RANGE(range, 1, 2); + + hr = ITextRange_MoveEnd(range, tomStory, 3, &delta); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(delta == 1, "got %d\n", delta); + CHECK_RANGE(range, 1, 12); + + RESET_RANGE(range, 2, 3); + + hr = ITextRange_MoveEnd(range, tomStory, -3, &delta); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(delta == -1, "got %d\n", delta); + CHECK_RANGE(range, 0, 0); + + hr = ITextRange_MoveEnd(range, tomStory, -1, &delta); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(delta == 0, "got %d\n", delta); + CHECK_RANGE(range, 0, 0); + + hr = ITextSelection_MoveEnd(selection, tomStory, 0, &delta); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(delta == 0, "got %d\n", delta); + CHECK_SELECTION(selection, 1, 2); + + hr = ITextSelection_MoveEnd(selection, tomStory, -1, &delta); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(delta == -1, "got %d\n", delta); + CHECK_SELECTION(selection, 0, 0); + + hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(delta == 1, "got %d\n", delta); + CHECK_SELECTION(selection, 0, 12); + + hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(delta == 0, "got %d\n", delta); + CHECK_SELECTION(selection, 0, 12); + + RESET_SELECTION(selection, 1, 2); + + hr = ITextSelection_MoveEnd(selection, tomStory, 3, &delta); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(delta == 1, "got %d\n", delta); + CHECK_SELECTION(selection, 1, 12); + + RESET_SELECTION(selection, 2, 3); + + hr = ITextSelection_MoveEnd(selection, tomStory, -3, &delta); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(delta == -1, "got %d\n", delta); + CHECK_SELECTION(selection, 0, 0); + + hr = ITextSelection_MoveEnd(selection, tomStory, -1, &delta); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(delta == 0, "got %d\n", delta); + CHECK_SELECTION(selection, 0, 0); + + release_interfaces(&hwnd, &reole, &doc, NULL); + + hr = ITextRange_MoveEnd(range, tomStory, 1, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextRange_MoveEnd(range, tomStory, 1, &delta); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_MoveEnd(selection, tomStory, 1, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + ITextSelection_Release(selection); + ITextRange_Release(range); +} + static void test_ITextRange_SetStart(void) { HWND w; @@ -3890,4 +4148,5 @@ START_TEST(richole) test_GetStoryLength(); test_ITextSelection_GetDuplicate(); test_Expand(); + test_MoveEnd(); } diff --git a/modules/rostests/winetests/riched20/txtsrv.c b/modules/rostests/winetests/riched20/txtsrv.c index 73ca7cd753..88b5adf13c 100644 --- a/modules/rostests/winetests/riched20/txtsrv.c +++ b/modules/rostests/winetests/riched20/txtsrv.c @@ -654,6 +654,7 @@ static void test_TxGetText(void) hres = ITextServices_TxGetText(txtserv, &rettext); ok(hres == S_OK, "ITextServices_TxGetText failed (result = %x)\n", hres); + SysFreeString(rettext); ITextServices_Release(txtserv); ITextHost_Release(host);
6 years, 6 months
1
0
0
0
01/01: [RICHED20] Sync with Wine Staging 3.9. CORE-14656
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aefc6e4447e33929b0373…
commit aefc6e4447e33929b037340756e486e87f9a55ba Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Mon Jun 4 03:48:07 2018 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Mon Jun 4 03:48:07 2018 +0100 [RICHED20] Sync with Wine Staging 3.9. CORE-14656 --- dll/win32/riched20/caret.c | 32 +++++++- dll/win32/riched20/editor.c | 60 ++++++++++++--- dll/win32/riched20/editor.h | 4 +- dll/win32/riched20/editstr.h | 9 ++- dll/win32/riched20/list.c | 8 +- dll/win32/riched20/richole.c | 176 +++++++++++++++++++++++++++++++++++-------- dll/win32/riched20/run.c | 2 +- dll/win32/riched20/writer.c | 6 +- media/doc/README.WINE | 2 +- 9 files changed, 244 insertions(+), 55 deletions(-) diff --git a/dll/win32/riched20/caret.c b/dll/win32/riched20/caret.c index d676a1bc38..4664f0ce09 100644 --- a/dll/win32/riched20/caret.c +++ b/dll/win32/riched20/caret.c @@ -471,12 +471,26 @@ ME_InternalInsertTextFromCursor(ME_TextEditor *editor, int nCursor, return ME_InsertRunAtCursor(editor, p, style, str, len, flags); } +static struct re_object* create_re_object(const REOBJECT *reo) +{ + struct re_object *reobj = heap_alloc(sizeof(*reobj)); + + if (!reobj) + { + WARN("Fail to allocate re_object.\n"); + return NULL; + } + ME_CopyReObject(&reobj->obj, reo, REO_GETOBJ_ALL_INTERFACES); + return reobj; +} void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor) { ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); ME_DisplayItem *di; WCHAR space = ' '; + ME_DisplayItem *di_prev = NULL; + struct re_object *reobj_prev = NULL; /* FIXME no no no */ if (ME_IsSelection(editor)) @@ -484,8 +498,22 @@ void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCur di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, MERF_GRAPHICS); - di->member.run.ole_obj = heap_alloc(sizeof(*reo)); - ME_CopyReObject(di->member.run.ole_obj, reo); + di->member.run.reobj = create_re_object(reo); + + di_prev = di; + while (ME_PrevRun(NULL, &di_prev, TRUE)) + { + if (di_prev->member.run.reobj) + { + reobj_prev = di_prev->member.run.reobj; + break; + } + } + if (reobj_prev) + list_add_after(&reobj_prev->entry, &di->member.run.reobj->entry); + else + list_add_head(&editor->reobj_list, &di->member.run.reobj->entry); + ME_ReleaseStyle(pStyle); } diff --git a/dll/win32/riched20/editor.c b/dll/win32/riched20/editor.c index c0843dd4e5..a883a963bd 100644 --- a/dll/win32/riched20/editor.c +++ b/dll/win32/riched20/editor.c @@ -90,7 +90,7 @@ + EM_REPLACESEL (proper style?) ANSI&Unicode + EM_SCROLL + EM_SCROLLCARET - - EM_SELECTIONTYPE + + EM_SELECTIONTYPE - EM_SETBIDIOPTIONS 3.0 + EM_SETBKGNDCOLOR + EM_SETCHARFORMAT (partly done, no ANSI) @@ -2964,23 +2964,57 @@ static void ME_SetDefaultFormatRect(ME_TextEditor *editor) editor->rcFormat.right -= 1; } +static LONG ME_GetSelectionType(ME_TextEditor *editor) +{ + LONG sel_type = SEL_EMPTY; + LONG start, end; + + ME_GetSelectionOfs(editor, &start, &end); + if (start == end) + sel_type = SEL_EMPTY; + else + { + LONG object_count = 0, character_count = 0; + int i; + + for (i = 0; i < end - start; i++) + { + ME_Cursor cursor; + + ME_CursorFromCharOfs(editor, start + i, &cursor); + if (cursor.pRun->member.run.reobj) + object_count++; + else + character_count++; + if (character_count >= 2 && object_count >= 2) + return (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT); + } + if (character_count) + { + sel_type |= SEL_TEXT; + if (character_count >= 2) + sel_type |= SEL_MULTICHAR; + } + if (object_count) + { + sel_type |= SEL_OBJECT; + if (object_count >= 2) + sel_type |= SEL_MULTIOBJECT; + } + } + return sel_type; +} + static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y) { CHARRANGE selrange; HMENU menu; - int seltype = 0; + int seltype; + if(!editor->lpOleCallback || !editor->hWnd) return FALSE; ME_GetSelectionOfs(editor, &selrange.cpMin, &selrange.cpMax); - if(selrange.cpMin == selrange.cpMax) - seltype |= SEL_EMPTY; - else - { - /* FIXME: Handle objects */ - seltype |= SEL_TEXT; - if(selrange.cpMax-selrange.cpMin > 1) - seltype |= SEL_MULTICHAR; - } + seltype = ME_GetSelectionType(editor); if(SUCCEEDED(IRichEditOleCallback_GetContextMenu(editor->lpOleCallback, seltype, NULL, &selrange, &menu))) { TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, editor->hwndParent, NULL); @@ -3117,6 +3151,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->wheel_remain = 0; list_init( &ed->style_list ); + list_init( &ed->reobj_list ); OleInitialize(NULL); return ed; @@ -3501,7 +3536,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS) UNSUPPORTED_MSG(EM_GETUNDONAME) UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX) - UNSUPPORTED_MSG(EM_SELECTIONTYPE) UNSUPPORTED_MSG(EM_SETBIDIOPTIONS) UNSUPPORTED_MSG(EM_SETEDITSTYLE) UNSUPPORTED_MSG(EM_SETLANGOPTIONS) @@ -3817,6 +3851,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, ME_UpdateRepaint(editor, FALSE); return len; } + case EM_SELECTIONTYPE: + return ME_GetSelectionType(editor); case EM_SETBKGNDCOLOR: { LRESULT lColor; diff --git a/dll/win32/riched20/editor.h b/dll/win32/riched20/editor.h index a4f53138f8..def11c325a 100644 --- a/dll/win32/riched20/editor.h +++ b/dll/win32/riched20/editor.h @@ -233,8 +233,8 @@ int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN; LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) DECLSPEC_HIDDEN; void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, BOOL selected) DECLSPEC_HIDDEN; void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) DECLSPEC_HIDDEN; -void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) DECLSPEC_HIDDEN; -void ME_DeleteReObject(REOBJECT* reo) DECLSPEC_HIDDEN; +void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) DECLSPEC_HIDDEN; +void ME_DeleteReObject(struct re_object *re_object) DECLSPEC_HIDDEN; void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) DECLSPEC_HIDDEN; /* editor.c */ diff --git a/dll/win32/riched20/editstr.h b/dll/win32/riched20/editstr.h index a37c4de46e..206ce85287 100644 --- a/dll/win32/riched20/editstr.h +++ b/dll/win32/riched20/editstr.h @@ -153,6 +153,12 @@ typedef enum { struct tagME_DisplayItem; +struct re_object +{ + struct list entry; + REOBJECT obj; +}; + typedef struct tagME_Run { ME_Style *style; @@ -163,7 +169,7 @@ typedef struct tagME_Run int nFlags; int nAscent, nDescent; /* pixels above/below baseline */ POINT pt; /* relative to para's position */ - REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */ + struct re_object *reobj; /* FIXME: should be a union with strText (at least) */ SCRIPT_ANALYSIS script_analysis; int num_glyphs, max_glyphs; @@ -436,6 +442,7 @@ typedef struct tagME_TextEditor BOOL bMouseCaptured; int wheel_remain; struct list style_list; + struct list reobj_list; } ME_TextEditor; typedef struct tagME_Context diff --git a/dll/win32/riched20/list.c b/dll/win32/riched20/list.c index 58b64e8081..ba35a90a98 100644 --- a/dll/win32/riched20/list.c +++ b/dll/win32/riched20/list.c @@ -97,7 +97,7 @@ BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) { if (p->type == diParagraph) { if (!all_para) return FALSE; - if (p->member.para.prev_para->type == diParagraph) + if (para && p->member.para.prev_para->type == diParagraph) *para = p->member.para.prev_para; } else if (p->type == diRun) { *run = p; @@ -169,7 +169,11 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item) if (item->type==diRun) { - if (item->member.run.ole_obj) ME_DeleteReObject(item->member.run.ole_obj); + if (item->member.run.reobj) + { + list_remove(&item->member.run.reobj->entry); + ME_DeleteReObject(item->member.run.reobj); + } heap_free( item->member.run.glyphs ); heap_free( item->member.run.clusters ); ME_ReleaseStyle(item->member.run.style); diff --git a/dll/win32/riched20/richole.c b/dll/win32/riched20/richole.c index 170c426e8a..91a656b3f3 100644 --- a/dll/win32/riched20/richole.c +++ b/dll/win32/riched20/richole.c @@ -1379,16 +1379,46 @@ IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob, REOBJECT *lpreobject, DWORD dwFlags) { IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); - return E_NOTIMPL; + struct re_object *reobj = NULL; + LONG count = 0; + + TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags); + + if (!lpreobject || !lpreobject->cbStruct) + return E_INVALIDARG; + + if (iob == REO_IOB_USE_CP) + { + ME_Cursor cursor; + + TRACE("character offset: %d\n", lpreobject->cp); + ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor); + if (!cursor.pRun->member.run.reobj) + return E_INVALIDARG; + else + reobj = cursor.pRun->member.run.reobj; + } + else + { + if (iob > IRichEditOle_GetObjectCount(me)) + return E_INVALIDARG; + LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry) + { + if (count == iob) + break; + count++; + } + } + ME_CopyReObject(lpreobject, &reobj->obj, dwFlags); + return S_OK; } static LONG WINAPI IRichEditOle_fnGetObjectCount(IRichEditOle *me) { IRichEditOleImpl *This = impl_from_IRichEditOle(me); - FIXME("stub %p\n",This); - return 0; + TRACE("(%p)\n",This); + return list_count(&This->editor->reobj_list); } static HRESULT WINAPI @@ -2170,17 +2200,63 @@ static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG cou return E_NOTIMPL; } +static HRESULT textrange_moveend(ITextRange *range, LONG unit, LONG count, LONG *delta) +{ + LONG old_start, old_end, new_start, new_end; + HRESULT hr = S_OK; + + if (!count) + { + if (delta) + *delta = 0; + return S_FALSE; + } + + ITextRange_GetStart(range, &old_start); + ITextRange_GetEnd(range, &old_end); + switch (unit) + { + case tomStory: + if (count < 0) + new_start = new_end = 0; + else + { + new_start = old_start; + ITextRange_GetStoryLength(range, &new_end); + } + if (delta) + { + if (new_end < old_end) + *delta = -1; + else if (new_end == old_end) + *delta = 0; + else + *delta = 1; + } + break; + default: + FIXME("unit %d is not supported\n", unit); + return E_NOTIMPL; + } + if (new_end == old_end) + hr = S_FALSE; + ITextRange_SetStart(range, new_start); + ITextRange_SetEnd(range, new_end); + + return hr; +} + static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count, LONG *delta) { ITextRangeImpl *This = impl_from_ITextRange(me); - FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); if (!This->child.reole) return CO_E_RELEASED; - return E_NOTIMPL; + return textrange_moveend(me, unit, count, delta); } static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count, @@ -4650,6 +4726,8 @@ static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value) static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font) { ITextSelectionImpl *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; TRACE("(%p)->(%p)\n", This, font); @@ -4659,12 +4737,16 @@ static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **f if (!font) return E_INVALIDARG; - return create_textfont((ITextRange*)me, NULL, font); + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = create_textfont(range, NULL, font); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font) { ITextSelectionImpl *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; TRACE("(%p)->(%p)\n", This, font); @@ -4674,13 +4756,17 @@ static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *fo if (!This->reOle) return CO_E_RELEASED; - textrange_set_font((ITextRange*)me, font); + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + textrange_set_font(range, font); + ITextRange_Release(range); return S_OK; } static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para) { ITextSelectionImpl *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; TRACE("(%p)->(%p)\n", This, para); @@ -4690,7 +4776,10 @@ static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **p if (!para) return E_INVALIDARG; - return create_textpara((ITextRange*)me, para); + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = create_textpara(range, para); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para) @@ -4755,13 +4844,18 @@ static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart) static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta) { ITextSelectionImpl *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; TRACE("(%p)->(%d %p)\n", This, unit, delta); if (!This->reOle) return CO_E_RELEASED; - return textrange_expand((ITextRange*)me, unit, delta); + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = textrange_expand(range, unit, delta); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index) @@ -4935,13 +5029,18 @@ static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LO LONG *delta) { ITextSelectionImpl *This = impl_from_ITextSelection(me); + ITextRange *range = NULL; + HRESULT hr; - FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); + TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); if (!This->reOle) return CO_E_RELEASED; - return E_NOTIMPL; + ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); + hr = textrange_moveend(range, unit, count, delta); + ITextRange_Release(range); + return hr; } static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count, @@ -5456,11 +5555,11 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) ENHMETAHEADER emh; assert(run->nFlags & MERF_GRAPHICS); - assert(run->ole_obj); + assert(run->reobj); - if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0) + if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0) { - convert_sizel(c, &run->ole_obj->sizel, pSize); + convert_sizel(c, &run->reobj->obj.sizel, pSize); if (c->editor->nZoomNumerator != 0) { pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); @@ -5469,13 +5568,13 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) return; } - if (!run->ole_obj->poleobj) + if (!run->reobj->obj.poleobj) { pSize->cx = pSize->cy = 0; return; } - if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK) + if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK) { FIXME("Query Interface IID_IDataObject failed!\n"); pSize->cx = pSize->cy = 0; @@ -5538,13 +5637,13 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) RECT rc; assert(run->nFlags & MERF_GRAPHICS); - assert(run->ole_obj); - if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK) + assert(run->reobj); + if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK) { FIXME("Couldn't get interface\n"); return; } - has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0; + has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0; fmt.cfFormat = CF_BITMAP; fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; @@ -5571,7 +5670,7 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) old_bm = SelectObject(hMemDC, stgm.u.hBitmap); if (has_size) { - convert_sizel(c, &run->ole_obj->sizel, &sz); + convert_sizel(c, &run->reobj->obj.sizel, &sz); } else { sz.cx = dibsect.dsBm.bmWidth; sz.cy = dibsect.dsBm.bmHeight; @@ -5591,7 +5690,7 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); if (has_size) { - convert_sizel(c, &run->ole_obj->sizel, &sz); + convert_sizel(c, &run->reobj->obj.sizel, &sz); } else { sz.cx = emh.rclBounds.right - emh.rclBounds.left; sz.cy = emh.rclBounds.bottom - emh.rclBounds.top; @@ -5619,21 +5718,36 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT); } -void ME_DeleteReObject(REOBJECT* reo) +void ME_DeleteReObject(struct re_object *reobj) { - if (reo->poleobj) IOleObject_Release(reo->poleobj); - if (reo->pstg) IStorage_Release(reo->pstg); - if (reo->polesite) IOleClientSite_Release(reo->polesite); - heap_free(reo); + if (reobj->obj.poleobj) IOleObject_Release(reobj->obj.poleobj); + if (reobj->obj.pstg) IStorage_Release(reobj->obj.pstg); + if (reobj->obj.polesite) IOleClientSite_Release(reobj->obj.polesite); + heap_free(reobj); } -void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) +void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) { *dst = *src; + dst->poleobj = NULL; + dst->pstg = NULL; + dst->polesite = NULL; - if (dst->poleobj) IOleObject_AddRef(dst->poleobj); - if (dst->pstg) IStorage_AddRef(dst->pstg); - if (dst->polesite) IOleClientSite_AddRef(dst->polesite); + if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj) + { + dst->poleobj = src->poleobj; + IOleObject_AddRef(dst->poleobj); + } + if ((flags & REO_GETOBJ_PSTG) && src->pstg) + { + dst->pstg = src->pstg; + IStorage_AddRef(dst->pstg); + } + if ((flags & REO_GETOBJ_POLESITE) && src->polesite) + { + dst->polesite = src->polesite; + IOleClientSite_AddRef(dst->polesite); + } } void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) diff --git a/dll/win32/riched20/run.c b/dll/win32/riched20/run.c index 445bbc2f91..3c7b38e2f6 100644 --- a/dll/win32/riched20/run.c +++ b/dll/win32/riched20/run.c @@ -295,7 +295,7 @@ ME_DisplayItem *ME_MakeRun(ME_Style *s, int nFlags) { ME_DisplayItem *item = ME_MakeDI(diRun); item->member.run.style = s; - item->member.run.ole_obj = NULL; + item->member.run.reobj = NULL; item->member.run.nFlags = nFlags; item->member.run.nCharOfs = -1; item->member.run.len = 0; diff --git a/dll/win32/riched20/writer.c b/dll/win32/riched20/writer.c index aad2e44879..b1e99d642f 100644 --- a/dll/win32/riched20/writer.c +++ b/dll/win32/riched20/writer.c @@ -947,7 +947,7 @@ static BOOL stream_out_graphics( ME_TextEditor *editor, ME_OutStream *stream, SIZE goal, pic; ME_Context c; - hr = IOleObject_QueryInterface( run->ole_obj->poleobj, &IID_IDataObject, (void **)&data ); + hr = IOleObject_QueryInterface( run->reobj->obj.poleobj, &IID_IDataObject, (void **)&data ); if (FAILED(hr)) return FALSE; ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) ); @@ -975,8 +975,8 @@ static BOOL stream_out_graphics( ME_TextEditor *editor, ME_OutStream *stream, emf_bits->szlMillimeters.cy * c.dpi.cy * 10 ); /* convert goal size to twips */ - goal.cx = MulDiv( run->ole_obj->sizel.cx, 144, 254 ); - goal.cy = MulDiv( run->ole_obj->sizel.cy, 144, 254 ); + goal.cx = MulDiv( run->reobj->obj.sizel.cx, 144, 254 ); + goal.cy = MulDiv( run->reobj->obj.sizel.cy, 144, 254 ); if (!ME_StreamOutPrint( stream, "{\\*\\shppict{\\pict\\emfblip\\picw%d\\pich%d\\picwgoal%d\\pichgoal%d\n", pic.cx, pic.cy, goal.cx, goal.cy )) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 58991828bb..4e58c6349f 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -158,7 +158,7 @@ reactos/dll/win32/qmgrprxy # Synced to WineStaging-2.9 reactos/dll/win32/query # Synced to WineStaging-3.3 reactos/dll/win32/rasapi32 # Synced to WineStaging-3.3 reactos/dll/win32/resutils # Synced to WineStaging-3.3 -reactos/dll/win32/riched20 # Synced to WineStaging-3.3 +reactos/dll/win32/riched20 # Synced to WineStaging-3.9 reactos/dll/win32/riched32 # Synced to WineStaging-3.3 reactos/dll/win32/rpcrt4 # Synced to WineStaging-3.3 reactos/dll/win32/rsabase # Synced to WineStaging-3.3
6 years, 6 months
1
0
0
0
← Newer
1
...
10
11
12
13
14
15
16
17
18
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Results per page:
10
25
50
100
200