winehq.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
2025
February
January
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
January
2003
December
November
October
September
August
July
June
May
April
March
February
January
2002
December
November
October
September
August
July
June
May
April
March
February
January
2001
December
November
October
September
August
July
June
May
April
March
February
List overview
wine-commits
June 2024
----- 2025 -----
February 2025
January 2025
----- 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
January 2004
----- 2003 -----
December 2003
November 2003
October 2003
September 2003
August 2003
July 2003
June 2003
May 2003
April 2003
March 2003
February 2003
January 2003
----- 2002 -----
December 2002
November 2002
October 2002
September 2002
August 2002
July 2002
June 2002
May 2002
April 2002
March 2002
February 2002
January 2002
----- 2001 -----
December 2001
November 2001
October 2001
September 2001
August 2001
July 2001
June 2001
May 2001
April 2001
March 2001
February 2001
wine-commits@winehq.org
1 participants
613 discussions
Start a n
N
ew thread
Rémi Bernon : win32u: Remove now unused vulkan_funcs in d3dkmt.c.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: 6e526d19f71fcbef4654281d6e96276a737a5f9b URL:
https://gitlab.winehq.org/wine/wine/-/commit/6e526d19f71fcbef4654281d6e9627…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Wed Jun 12 10:49:54 2024 +0200 win32u: Remove now unused vulkan_funcs in d3dkmt.c. --- dlls/win32u/d3dkmt.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dlls/win32u/d3dkmt.c b/dlls/win32u/d3dkmt.c index a97ab5d3c33..d6eedc44a9b 100644 --- a/dlls/win32u/d3dkmt.c +++ b/dlls/win32u/d3dkmt.c @@ -65,7 +65,6 @@ static PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryPro static PFN_vkGetPhysicalDeviceMemoryProperties pvkGetPhysicalDeviceMemoryProperties; static PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; static PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; -static const struct vulkan_funcs *vulkan_funcs; static void d3dkmt_init_vulkan(void) { @@ -94,7 +93,6 @@ static void d3dkmt_init_vulkan(void) if ((vr = p_vkCreateInstance( &create_info, NULL, &d3dkmt_vk_instance ))) { WARN( "Failed to create a Vulkan instance, vr %d.\n", vr ); - vulkan_funcs = NULL; return; } @@ -104,7 +102,7 @@ static void d3dkmt_init_vulkan(void) { \ WARN( "Failed to load " #f ".\n" ); \ p_vkDestroyInstance( d3dkmt_vk_instance, NULL ); \ - vulkan_funcs = NULL; \ + d3dkmt_vk_instance = NULL; \ return; \ } LOAD_VK_FUNC( vkEnumeratePhysicalDevices ) @@ -118,7 +116,7 @@ static BOOL d3dkmt_use_vulkan(void) { static pthread_once_t once = PTHREAD_ONCE_INIT; pthread_once( &once, d3dkmt_init_vulkan ); - return !!vulkan_funcs; + return !!d3dkmt_vk_instance; } /* d3dkmt_lock must be held */
1
0
0
0
Jacek Caban : mshtml: Add support for using apply on builtin function objects.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: ec17fc4ca3ed83ca4c996e76339551a73491e247 URL:
https://gitlab.winehq.org/wine/wine/-/commit/ec17fc4ca3ed83ca4c996e76339551…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Thu Jun 20 00:27:43 2024 +0200 mshtml: Add support for using apply on builtin function objects. Based on patch by Gabriel Ivăncescu. --- dlls/mshtml/dispex.c | 105 ++++++++++++++++++++++++++++++++++++++ dlls/mshtml/tests/documentmode.js | 15 ++++++ 2 files changed, 120 insertions(+) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 65e04343b88..c40b63cb980 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -799,6 +799,110 @@ static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags, return hres; } +static HRESULT get_disp_prop(IDispatchEx *dispex, const WCHAR *name, LCID lcid, VARIANT *res, + EXCEPINFO *ei, IServiceProvider *caller) +{ + DISPPARAMS dp = { 0 }; + DISPID dispid; + HRESULT hres; + BSTR bstr; + + if(!(bstr = SysAllocString(name))) + return E_OUTOFMEMORY; + hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &dispid); + SysFreeString(bstr); + if(SUCCEEDED(hres)) + hres = IDispatchEx_InvokeEx(dispex, dispid, lcid, DISPATCH_PROPERTYGET, &dp, res, ei, caller); + return hres; +} + +static HRESULT function_apply(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + IWineJSDispatchHost *this_iface; + DISPPARAMS params = { 0 }; + IDispatchEx *array = NULL; + UINT argc = 0; + VARIANT *arg; + HRESULT hres; + + arg = dp->rgvarg + dp->cArgs - 1; + if(dp->cArgs < 1 || V_VT(arg) != VT_DISPATCH || !V_DISPATCH(arg)) + return CTL_E_ILLEGALFUNCTIONCALL; + + hres = IDispatch_QueryInterface(V_DISPATCH(arg), &IID_IWineJSDispatchHost, (void**)&this_iface); + if(FAILED(hres)) + return CTL_E_ILLEGALFUNCTIONCALL; + + if(dp->cArgs >= 2) { + VARIANT length; + + arg--; + if(V_VT(arg) != VT_DISPATCH) { + hres = CTL_E_ILLEGALFUNCTIONCALL; + goto fail; + } + + /* FIXME: Native checks if it's an acual JS array. */ + hres = IDispatch_QueryInterface(V_DISPATCH(arg), &IID_IDispatchEx, (void**)&array); + if(FAILED(hres)) + goto fail; + + V_VT(&length) = VT_EMPTY; + hres = get_disp_prop(array, L"length", lcid, &length, ei, caller); + if(FAILED(hres)) { + if(hres == DISP_E_UNKNOWNNAME) + hres = CTL_E_ILLEGALFUNCTIONCALL; + goto fail; + } + if(V_VT(&length) != VT_I4) { + VARIANT tmp = length; + hres = change_type(&length, &tmp, VT_I4, caller); + if(FAILED(hres)) { + hres = CTL_E_ILLEGALFUNCTIONCALL; + goto fail; + } + } + if(V_I4(&length) < 0) { + hres = CTL_E_ILLEGALFUNCTIONCALL; + goto fail; + } + params.cArgs = V_I4(&length); + + /* alloc new params */ + if(params.cArgs) { + if(!(params.rgvarg = malloc(params.cArgs * sizeof(VARIANTARG)))) { + hres = E_OUTOFMEMORY; + goto fail; + } + for(argc = 0; argc < params.cArgs; argc++) { + WCHAR buf[12]; + + arg = params.rgvarg + params.cArgs - argc - 1; + swprintf(buf, ARRAY_SIZE(buf), L"%u", argc); + hres = get_disp_prop(array, buf, lcid, arg, ei, caller); + if(FAILED(hres)) { + if(hres == DISP_E_UNKNOWNNAME) { + V_VT(arg) = VT_EMPTY; + continue; + } + goto fail; + } + } + } + } + + hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, func->info->tid, ¶ms, res, ei, caller); + +fail: + while(argc--) + VariantClear(¶ms.rgvarg[params.cArgs - argc - 1]); + free(params.rgvarg); + if(array) + IDispatchEx_Release(array); + IWineJSDispatchHost_Release(this_iface); + return hres == E_UNEXPECTED ? CTL_E_ILLEGALFUNCTIONCALL : hres; +} + static HRESULT function_call(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { DISPPARAMS params = { dp->rgvarg, NULL, dp->cArgs - 1, 0 }; @@ -823,6 +927,7 @@ static const struct { const WCHAR *name; HRESULT (*invoke)(func_disp_t*,DISPPARAMS*,LCID,VARIANT*,EXCEPINFO*,IServiceProvider*); } function_props[] = { + { L"apply", function_apply }, { L"call", function_call } }; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 327d744f00d..c8ce01b0443 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -402,6 +402,21 @@ sync_test("builtin_obj", function() { elem2.onclick = function() { clicked = true; }; elem1.click.call(elem2); ok(clicked === true, "elem2.onclick not called"); + + elem1 = f.apply(document, ["div"]); + elem2 = f.apply(document, ["br"]); + document.body.appendChild(elem1); + document.body.appendChild(elem2); + elem1.onclick = function() { ok(false, "unexpected elem1.onclick"); }; + clicked = false; + elem2.onclick = function() { clicked = true; }; + elem1.click.apply(elem2); + ok(clicked === true, "elem2.onclick not called"); + + try { + elem1.click.apply(elem2, { length: -1 }); + ok(false, "exception expected"); + }catch(ex) {} }); sync_test("elem_props", function() {
1
0
0
0
Jacek Caban : mshtml: Add support for using call on builtin function objects.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: 7b95b93c4227673dad379483a85fc7c06212812a URL:
https://gitlab.winehq.org/wine/wine/-/commit/7b95b93c4227673dad379483a85fc7…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed Jun 5 14:33:50 2024 +0200 mshtml: Add support for using call on builtin function objects. Based on patch by Gabriel Ivăncescu. --- dlls/mshtml/dispex.c | 96 +++++++++++++++++++++++++++++++++++- dlls/mshtml/htmlwindow.c | 12 ++++- dlls/mshtml/mshtml_private_iface.idl | 1 + dlls/mshtml/tests/documentmode.js | 52 +++++++++++++++++++ 4 files changed, 159 insertions(+), 2 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index a6cb664469f..65e04343b88 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -799,6 +799,33 @@ static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags, return hres; } +static HRESULT function_call(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + DISPPARAMS params = { dp->rgvarg, NULL, dp->cArgs - 1, 0 }; + IWineJSDispatchHost *this_iface; + VARIANT *arg; + HRESULT hres; + + arg = dp->rgvarg + dp->cArgs - 1; + if(dp->cArgs < 1 || V_VT(arg) != VT_DISPATCH || !V_DISPATCH(arg)) + return CTL_E_ILLEGALFUNCTIONCALL; + + hres = IDispatch_QueryInterface(V_DISPATCH(arg), &IID_IWineJSDispatchHost, (void**)&this_iface); + if(FAILED(hres)) + return CTL_E_ILLEGALFUNCTIONCALL; + + hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, func->info->tid, ¶ms, res, ei, caller); + IWineJSDispatchHost_Release(this_iface); + return (hres == E_UNEXPECTED) ? CTL_E_ILLEGALFUNCTIONCALL : hres; +} + +static const struct { + const WCHAR *name; + HRESULT (*invoke)(func_disp_t*,DISPPARAMS*,LCID,VARIANT*,EXCEPINFO*,IServiceProvider*); +} function_props[] = { + { L"call", function_call } +}; + static inline func_disp_t *impl_from_DispatchEx(DispatchEx *iface) { return CONTAINING_RECORD(iface, func_disp_t, dispex); @@ -866,9 +893,58 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR return hres; } +static HRESULT function_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid) +{ + DWORD i; + + for(i = 0; i < ARRAY_SIZE(function_props); i++) { + if((flags & fdexNameCaseInsensitive) ? wcsicmp(name, function_props[i].name) : wcscmp(name, function_props[i].name)) + continue; + *dispid = MSHTML_DISPID_CUSTOM_MIN + i; + return S_OK; + } + return DISP_E_UNKNOWNNAME; +} + +static HRESULT function_get_name(DispatchEx *dispex, DISPID id, BSTR *name) +{ + DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN; + + if(idx >= ARRAY_SIZE(function_props)) + return DISP_E_MEMBERNOTFOUND; + + return (*name = SysAllocString(function_props[idx].name)) ? S_OK : E_OUTOFMEMORY; +} + +static HRESULT function_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + func_disp_t *This = impl_from_DispatchEx(dispex); + DWORD idx = id - MSHTML_DISPID_CUSTOM_MIN; + + if(idx >= ARRAY_SIZE(function_props)) + return DISP_E_MEMBERNOTFOUND; + + switch(flags) { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + if(!res) + return E_INVALIDARG; + /* fall through */ + case DISPATCH_METHOD: + return function_props[idx].invoke(This, params, lcid, res, ei, caller); + default: + return MSHTML_E_INVALID_PROPERTY; + } + + return S_OK; +} + static const dispex_static_data_vtbl_t function_dispex_vtbl = { .destructor = function_destructor, .value = function_value, + .get_dispid = function_get_dispid, + .get_name = function_get_name, + .invoke = function_invoke }; static const tid_t function_iface_tids[] = {0}; @@ -1980,6 +2056,23 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IWineJSDispatchHost *iface, return E_NOTIMPL; } +static HRESULT WINAPI DispatchEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret, + EXCEPINFO *ei, IServiceProvider *caller) +{ + DispatchEx *This = impl_from_IWineJSDispatchHost(iface); + func_info_t *func; + HRESULT hres; + + TRACE("%s (%p)->(%lx %x %p %p %p %p)\n", This->info->desc->name, This, id, iid, dp, ret, ei, caller); + + hres = get_builtin_func(This->info, id, &func); + if(FAILED(hres)) + return hres; + if(func->tid != iid || func->func_disp_idx < 0) + return E_UNEXPECTED; + return call_builtin_function(This, func, dp, ret, ei, caller); +} + static IWineJSDispatchHostVtbl JSDispatchHostVtbl = { DispatchEx_QueryInterface, DispatchEx_AddRef, @@ -1995,7 +2088,8 @@ static IWineJSDispatchHostVtbl JSDispatchHostVtbl = { DispatchEx_GetMemberProperties, DispatchEx_GetMemberName, DispatchEx_GetNextDispID, - DispatchEx_GetNameSpaceParent + DispatchEx_GetNameSpaceParent, + DispatchEx_CallFunction, }; static nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb) diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 1f4fe6ffd7a..cf0920783d7 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3440,6 +3440,15 @@ static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IWineJSDispatchHost *iface return S_OK; } +static HRESULT WINAPI WindowDispEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret, + EXCEPINFO *ei, IServiceProvider *caller) +{ + HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface); + + return IWineJSDispatchHost_CallFunction(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, + id, iid, dp, ret, ei, caller); +} + static const IWineJSDispatchHostVtbl WindowDispExVtbl = { WindowDispEx_QueryInterface, WindowDispEx_AddRef, @@ -3455,7 +3464,8 @@ static const IWineJSDispatchHostVtbl WindowDispExVtbl = { WindowDispEx_GetMemberProperties, WindowDispEx_GetMemberName, WindowDispEx_GetNextDispID, - WindowDispEx_GetNameSpaceParent + WindowDispEx_GetNameSpaceParent, + WindowDispEx_CallFunction, }; static inline HTMLOuterWindow *impl_from_IEventTarget(IEventTarget *iface) diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 46bf692b240..f4292e298d0 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -266,4 +266,5 @@ interface IWineXMLHttpRequestPrivate : IDispatch ] interface IWineJSDispatchHost : IDispatchEx { + HRESULT CallFunction(DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); } diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 23fd2128e5f..327d744f00d 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -352,6 +352,58 @@ sync_test("builtin_toString", function() { } }); +sync_test("builtin_obj", function() { + var v = document.documentMode; + var f = document.createElement; + var e; + + if(v < 9) { + ok(!(window instanceof Object), "window instance of Object"); + ok(!(document instanceof Object), "document instance of Object"); + ok(!("arguments" in f), "arguments in f"); + ok(!("length" in f), "length in f"); + e = 0; + try { + f.toString(); + }catch(ex) { + e = ex.number; + } + ok(e === 0xa01b6 - 0x80000000, "[f.toString] e = " + e); + try { + window.toString.call(null); + ok(false, "expected exception calling window.toString with null context"); + }catch(ex) {} + } + + e = 0; + try { + f.call(Object, "div"); + }catch(ex) { + e = ex.number; + } + todo_wine_if(v >= 9). + ok(e === (v < 9 ? 0xa0005 : 0x0ffff) - 0x80000000, "[f.call(Object, 'div')] e = " + e); + + e = 0; + try { + f.call(null, "div"); + }catch(ex) { + e = ex.number; + } + todo_wine_if(v >= 9). + ok(e === (v < 9 ? 0xa0005 : 0x0ffff) - 0x80000000, "[f.call(null, 'div')] e = " + e); + + var elem1 = f.call(document, "div"); + var elem2 = f.call(document, "br"); + document.body.appendChild(elem1); + document.body.appendChild(elem2); + elem1.onclick = function() { ok(false, "unexpected elem1.onclick"); }; + var clicked = false; + elem2.onclick = function() { clicked = true; }; + elem1.click.call(elem2); + ok(clicked === true, "elem2.onclick not called"); +}); + sync_test("elem_props", function() { var elem = document.documentElement;
1
0
0
0
Jacek Caban : mshtml: Rename builtin function helpers.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: 005e164751002caf2ce781c743b32518f8549f30 URL:
https://gitlab.winehq.org/wine/wine/-/commit/005e164751002caf2ce781c743b325…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed Jun 5 19:28:32 2024 +0200 mshtml: Rename builtin function helpers. --- dlls/mshtml/dispex.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index ab901908901..a6cb664469f 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1161,8 +1161,8 @@ static HRESULT builtin_propput(DispatchEx *This, func_info_t *func, DISPPARAMS * return hres; } -static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, - VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +static HRESULT call_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { VARIANT arg_buf[MAX_ARGS], *arg_ptrs[MAX_ARGS], *arg, retv, ret_ref, vhres; unsigned i, nconv = 0; @@ -1268,7 +1268,7 @@ static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISP return V_ERROR(&vhres); } -static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, +static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { HRESULT hres; @@ -1299,7 +1299,7 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, } } - hres = invoke_builtin_function(This, func, dp, res, ei, caller); + hres = call_builtin_function(This, func, dp, res, ei, caller); break; case DISPATCH_PROPERTYGET: { func_obj_entry_t *entry; @@ -1365,7 +1365,7 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD return hres; if(func->func_disp_idx >= 0) - return function_invoke(This, func, flags, dp, res, ei, caller); + return invoke_builtin_function(This, func, flags, dp, res, ei, caller); if(func->hook) { hres = func->hook(This, flags, dp, res, ei, caller); @@ -1422,7 +1422,7 @@ HRESULT dispex_call_builtin(DispatchEx *dispex, DISPID id, DISPPARAMS *dp, if(FAILED(hres)) return hres; - return invoke_builtin_function(dispex, func, dp, res, ei, caller); + return call_builtin_function(dispex, func, dp, res, ei, caller); } HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
1
0
0
0
Jacek Caban : mshtml: Introduce IWineJSDispatchHost interface.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: bea627b646f190865fe84880a6c22c83643f471e URL:
https://gitlab.winehq.org/wine/wine/-/commit/bea627b646f190865fe84880a6c22c…
Author: Jacek Caban <jacek(a)codeweavers.com> Date: Tue Jun 4 18:17:00 2024 +0200 mshtml: Introduce IWineJSDispatchHost interface. Based on patch by Gabriel Ivăncescu. --- dlls/mshtml/dispex.c | 130 ++++++++++++++++++----------------- dlls/mshtml/htmlattr.c | 6 +- dlls/mshtml/htmldoc.c | 4 +- dlls/mshtml/htmlelem.c | 22 +++--- dlls/mshtml/htmlelemcol.c | 2 +- dlls/mshtml/htmlevent.c | 6 +- dlls/mshtml/htmlframe.c | 4 +- dlls/mshtml/htmlstyle.c | 2 +- dlls/mshtml/htmlwindow.c | 81 +++++++++++----------- dlls/mshtml/mshtml_private.h | 18 ++--- dlls/mshtml/mshtml_private_iface.idl | 9 +++ dlls/mshtml/mutation.c | 2 +- dlls/mshtml/oleobj.c | 18 ++--- dlls/mshtml/omnavigator.c | 2 +- dlls/mshtml/script.c | 6 +- 15 files changed, 162 insertions(+), 150 deletions(-)
1
0
0
0
Rémi Bernon : win32u: Use the desktop shared data for GetCursorPos.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: 81eafa9b78aeece8983349fc9aee5d0fbe98daa2 URL:
https://gitlab.winehq.org/wine/wine/-/commit/81eafa9b78aeece8983349fc9aee5d…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Thu Apr 25 14:40:41 2024 +0200 win32u: Use the desktop shared data for GetCursorPos. Based on a patch by Huw Davies. --- dlls/win32u/input.c | 18 +++++++++--------- dlls/win32u/win32u_private.h | 8 ++++++++ dlls/win32u/winstation.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 5b25086cb6f..2fbe21e56af 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -740,22 +740,22 @@ BOOL WINAPI NtUserSetCursorPos( INT x, INT y ) */ BOOL get_cursor_pos( POINT *pt ) { + struct object_lock lock = OBJECT_LOCK_INIT; + const desktop_shm_t *desktop_shm; BOOL ret; - DWORD last_change; + DWORD last_change = 0; + NTSTATUS status; UINT dpi; if (!pt) return FALSE; - SERVER_START_REQ( set_cursor ) + while ((status = get_shared_desktop( &lock, &desktop_shm )) == STATUS_PENDING) { - if ((ret = !wine_server_call( req ))) - { - pt->x = reply->new_x; - pt->y = reply->new_y; - last_change = reply->last_change; - } + pt->x = desktop_shm->cursor.x; + pt->y = desktop_shm->cursor.y; + last_change = desktop_shm->cursor.last_change; } - SERVER_END_REQ; + ret = !status; /* query new position from graphics driver if we haven't updated recently */ if (ret && NtGetTickCount() - last_change > 100) ret = user_driver->pGetCursorPos( pt ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index bc6f5aadc19..f7ba2c1a423 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -213,6 +213,14 @@ struct object_lock }; #define OBJECT_LOCK_INIT {0} +/* Get shared session object's data pointer, must be called in a loop while STATUS_PENDING + * is returned, lock must be initialized with OBJECT_LOCK_INIT. + * + * The data read from the objects may be transient and no logic should be executed based + * on it, within the loop, or after, unless the function has returned STATUS_SUCCESS. + */ +extern NTSTATUS get_shared_desktop( struct object_lock *lock, const desktop_shm_t **desktop_shm ); + extern BOOL is_virtual_desktop(void); /* window.c */ diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index f1679ac7928..7168a614735 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -184,6 +184,41 @@ static const shared_object_t *find_shared_session_object( obj_locator_t locator return NULL; } +NTSTATUS get_shared_desktop( struct object_lock *lock, const desktop_shm_t **desktop_shm ) +{ + struct session_thread_data *data = get_session_thread_data(); + const shared_object_t *object; + + TRACE( "lock %p, desktop_shm %p\n", lock, desktop_shm ); + + if (!(object = data->shared_desktop)) + { + obj_locator_t locator; + + SERVER_START_REQ( get_thread_desktop ) + { + req->tid = GetCurrentThreadId(); + wine_server_call( req ); + locator = reply->locator; + } + SERVER_END_REQ; + + data->shared_desktop = find_shared_session_object( locator ); + if (!(object = data->shared_desktop)) return STATUS_INVALID_HANDLE; + memset( lock, 0, sizeof(*lock) ); + } + + if (!lock->id || !shared_object_release_seqlock( object, lock->seq )) + { + shared_object_acquire_seqlock( object, &lock->seq ); + *desktop_shm = &object->shm.desktop; + lock->id = object->id; + return STATUS_PENDING; + } + + return STATUS_SUCCESS; +} + BOOL is_virtual_desktop(void) { HANDLE desktop = NtUserGetThreadDesktop( GetCurrentThreadId() );
1
0
0
0
Rémi Bernon : server: Move the last cursor time to the desktop session object.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: 5488d99b3ebde64f2407e161a033da4c759bdb6c URL:
https://gitlab.winehq.org/wine/wine/-/commit/5488d99b3ebde64f2407e161a033da…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Mon Feb 19 22:17:27 2024 +0100 server: Move the last cursor time to the desktop session object. Based on a patch by Huw Davies. --- include/wine/server_protocol.h | 3 ++- server/protocol.def | 1 + server/queue.c | 17 +++++++++++------ server/user.h | 1 - server/winstation.c | 1 + 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 9d12ad850a5..df31a957486 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -887,6 +887,7 @@ struct shared_cursor { int x; int y; + unsigned int last_change; }; typedef volatile struct @@ -6566,7 +6567,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 812 +#define SERVER_PROTOCOL_VERSION 813 /* ### protocol_version end ### */ diff --git a/server/protocol.def b/server/protocol.def index 1b64c3da1eb..20ed82982dd 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -903,6 +903,7 @@ struct shared_cursor { int x; /* cursor position */ int y; + unsigned int last_change; /* time of last position change */ }; typedef volatile struct diff --git a/server/queue.c b/server/queue.c index a1dbd133209..c2e957cfd21 100644 --- a/server/queue.c +++ b/server/queue.c @@ -469,6 +469,7 @@ static int update_desktop_cursor_pos( struct desktop *desktop, user_handle_t win { const desktop_shm_t *desktop_shm = desktop->shared; int updated; + unsigned int time = get_tick_count(); x = max( min( x, desktop->cursor.clip.right - 1 ), desktop->cursor.clip.left ); y = max( min( y, desktop->cursor.clip.bottom - 1 ), desktop->cursor.clip.top ); @@ -478,11 +479,10 @@ static int update_desktop_cursor_pos( struct desktop *desktop, user_handle_t win updated = shared->cursor.x != x || shared->cursor.y != y; shared->cursor.x = x; shared->cursor.y = y; + shared->cursor.last_change = time; } SHARED_WRITE_END; - desktop->cursor.last_change = get_tick_count(); - if (!win || !is_window_visible( win ) || is_window_transparent( win )) win = shallow_window_from_point( desktop, x, y ); if (update_desktop_cursor_window( desktop, win )) updated = 1; @@ -1998,7 +1998,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons struct rawinput_message raw_msg; struct message *msg; struct thread *foreground; - unsigned int i, time, flags; + unsigned int i, time = get_tick_count(), flags; struct hw_msg_source source = { IMDT_MOUSE, origin }; lparam_t wparam = input->mouse.data << 16; int wait = 0, x, y; @@ -2020,10 +2020,15 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons WM_MOUSEHWHEEL /* 0x1000 = MOUSEEVENTF_HWHEEL */ }; - desktop->cursor.last_change = get_tick_count(); + SHARED_WRITE_BEGIN( desktop_shm, desktop_shm_t ) + { + shared->cursor.last_change = time; + } + SHARED_WRITE_END; + flags = input->mouse.flags; time = input->mouse.time; - if (!time) time = desktop->cursor.last_change; + if (!time) time = desktop_shm->cursor.last_change; if (flags & MOUSEEVENTF_MOVE) { @@ -3741,7 +3746,7 @@ DECL_HANDLER(set_cursor) reply->new_x = desktop_shm->cursor.x; reply->new_y = desktop_shm->cursor.y; reply->new_clip = desktop->cursor.clip; - reply->last_change = desktop->cursor.last_change; + reply->last_change = desktop_shm->cursor.last_change; } /* Get the history of the 64 last cursor positions */ diff --git a/server/user.h b/server/user.h index e6f8a39e5ea..a20aff99284 100644 --- a/server/user.h +++ b/server/user.h @@ -58,7 +58,6 @@ struct global_cursor { rectangle_t clip; /* cursor clip rectangle */ unsigned int clip_flags; /* last cursor clip flags */ - unsigned int last_change; /* time of last position change */ user_handle_t win; /* window that contains the cursor */ }; diff --git a/server/winstation.c b/server/winstation.c index 2f07eeaa134..87981f64167 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -309,6 +309,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned { shared->cursor.x = 0; shared->cursor.y = 0; + shared->cursor.last_change = 0; } SHARED_WRITE_END; }
1
0
0
0
Rémi Bernon : server: Move the cursor position to the desktop session object.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: 728049d6fa23a23cfe10cd5e04e8198b7300e9f8 URL:
https://gitlab.winehq.org/wine/wine/-/commit/728049d6fa23a23cfe10cd5e04e819…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Sun Apr 28 11:05:31 2024 +0200 server: Move the cursor position to the desktop session object. Based on a patch by Huw Davies. --- include/wine/server_protocol.h | 10 ++++-- server/protocol.def | 8 ++++- server/queue.c | 78 ++++++++++++++++++++++++++---------------- server/user.h | 2 -- server/winstation.c | 7 ++++ 5 files changed, 70 insertions(+), 35 deletions(-)
1
0
0
0
Rémi Bernon : win32u: Open the desktop shared object in NtUserSetThreadDesktop.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: eb63ac74dc3679ab41eef1afe9b3a255d2963e1d URL:
https://gitlab.winehq.org/wine/wine/-/commit/eb63ac74dc3679ab41eef1afe9b3a2…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Mon Feb 19 21:45:30 2024 +0100 win32u: Open the desktop shared object in NtUserSetThreadDesktop. --- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/sysparams.c | 1 + dlls/win32u/win32u_private.h | 8 +++ dlls/win32u/winstation.c | 149 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 158 insertions(+), 1 deletion(-) diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 62e65d71d31..39943e2261b 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -124,6 +124,7 @@ struct user_thread_info UINT spy_indent; /* Current spy indent */ BOOL clipping_cursor; /* thread is currently clipping */ DWORD clipping_reset; /* time when clipping was last reset */ + struct session_thread_data *session_data; /* shared session thread data */ }; C_ASSERT( sizeof(struct user_thread_info) <= sizeof(((TEB *)0)->Win32ClientInfo) ); diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 71e52b71719..34de10168e2 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -6340,6 +6340,7 @@ static void thread_detach(void) cleanup_imm_thread(); NtClose( thread_info->server_queue ); + free( thread_info->session_data ); exiting_thread_id = 0; } diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 96517ef081a..bc6f5aadc19 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -205,6 +205,14 @@ extern void free_vulkan_gpu( struct vulkan_gpu *gpu ); extern BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ); /* winstation.c */ + +struct object_lock +{ + UINT64 id; + UINT64 seq; +}; +#define OBJECT_LOCK_INIT {0} + extern BOOL is_virtual_desktop(void); /* window.c */ diff --git a/dlls/win32u/winstation.c b/dlls/win32u/winstation.c index 3e71218200a..f1679ac7928 100644 --- a/dlls/win32u/winstation.c +++ b/dlls/win32u/winstation.c @@ -22,9 +22,14 @@ #pragma makedep unix #endif +#include <assert.h> +#include <stdarg.h> +#include <stddef.h> + +#include <pthread.h> + #include "ntstatus.h" #define WIN32_NO_STATUS -#include <stdarg.h> #include "windef.h" #include "winbase.h" #include "ntuser.h" @@ -40,6 +45,145 @@ WINE_DECLARE_DEBUG_CHANNEL(win); #define DESKTOP_ALL_ACCESS 0x01ff +struct session_thread_data +{ + const shared_object_t *shared_desktop; /* thread desktop shared session cached object */ +}; + +struct session_block +{ + struct list entry; /* entry in the session block list */ + const char *data; /* base pointer for the mmaped data */ + SIZE_T offset; /* offset of data in the session shared mapping */ + SIZE_T size; /* size of the mmaped data */ +}; + +static pthread_mutex_t session_lock = PTHREAD_MUTEX_INITIALIZER; +static struct list session_blocks = LIST_INIT(session_blocks); + +static struct session_thread_data *get_session_thread_data(void) +{ + struct user_thread_info *thread_info = get_user_thread_info(); + if (!thread_info->session_data) thread_info->session_data = calloc(1, sizeof(*thread_info->session_data)); + return thread_info->session_data; +} + +#if defined(__i386__) || defined(__x86_64__) +/* this prevents compilers from incorrectly reordering non-volatile reads (e.g., memcpy) from shared memory */ +#define __SHARED_READ_FENCE do { __asm__ __volatile__( "" ::: "memory" ); } while (0) +#else +#define __SHARED_READ_FENCE __atomic_thread_fence( __ATOMIC_ACQUIRE ) +#endif + +static void shared_object_acquire_seqlock( const shared_object_t *object, UINT64 *seq ) +{ + while ((*seq = ReadNoFence64( &object->seq )) & 1) YieldProcessor(); + __SHARED_READ_FENCE; +} + +static BOOL shared_object_release_seqlock( const shared_object_t *object, UINT64 seq ) +{ + __SHARED_READ_FENCE; + return ReadNoFence64( &object->seq ) == seq; +} + +static object_id_t shared_object_get_id( const shared_object_t *object ) +{ + struct object_lock lock = OBJECT_LOCK_INIT; + do + { + shared_object_acquire_seqlock( object, &lock.seq ); + lock.id = object->id; + } while (!shared_object_release_seqlock( object, lock.seq )); + return lock.id; +} + +static NTSTATUS map_shared_session_block( SIZE_T offset, SIZE_T size, struct session_block **ret ) +{ + static const WCHAR nameW[] = + { + '\\','K','e','r','n','e','l','O','b','j','e','c','t','s','\\', + '_','_','w','i','n','e','_','s','e','s','s','i','o','n',0 + }; + UNICODE_STRING name = RTL_CONSTANT_STRING( nameW ); + LARGE_INTEGER off = {.QuadPart = offset - (offset % system_info.AllocationGranularity)}; + struct session_block *block; + OBJECT_ATTRIBUTES attr; + unsigned int status; + HANDLE handle; + + assert( offset + size > offset ); + + if (!(block = calloc( 1, sizeof(*block) ))) return STATUS_NO_MEMORY; + + InitializeObjectAttributes( &attr, &name, 0, NULL, NULL ); + if ((status = NtOpenSection( &handle, SECTION_MAP_READ, &attr ))) + WARN( "Failed to open shared session section, status %#x\n", status ); + else + { + if ((status = NtMapViewOfSection( handle, GetCurrentProcess(), (void **)&block->data, 0, 0, + &off, &block->size, ViewUnmap, 0, PAGE_READONLY ))) + WARN( "Failed to map shared session block, status %#x\n", status ); + else + { + list_add_tail( &session_blocks, &block->entry ); + block->offset = off.QuadPart; + assert( block->offset + block->size > block->offset ); + } + NtClose( handle ); + } + + if (status) free( block ); + else *ret = block; + return status; +} + +static NTSTATUS find_shared_session_block( SIZE_T offset, SIZE_T size, struct session_block **ret ) +{ + struct session_block *block; + UINT status; + + assert( offset + size > offset ); + + pthread_mutex_lock( &session_lock ); + + LIST_FOR_EACH_ENTRY( block, &session_blocks, struct session_block, entry ) + { + if (block->offset < offset && offset + size <= block->offset + block->size) + { + *ret = block; + pthread_mutex_unlock( &session_lock ); + return STATUS_SUCCESS; + } + } + + if ((status = map_shared_session_block( offset, size, ret ))) + { + WARN( "Failed to map session block for offset %s, size %s, status %#x\n", + wine_dbgstr_longlong(offset), wine_dbgstr_longlong(size), status ); + } + + pthread_mutex_unlock( &session_lock ); + + return status; +} + +static const shared_object_t *find_shared_session_object( obj_locator_t locator ) +{ + const shared_object_t *object; + struct session_block *block; + NTSTATUS status; + + if (locator.id && !(status = find_shared_session_block( locator.offset, sizeof(*object), &block ))) + { + object = (const shared_object_t *)(block->data + locator.offset - block->offset); + if (locator.id == shared_object_get_id( object )) return object; + WARN( "Session object id doesn't match expected id %s\n", wine_dbgstr_longlong(locator.id) ); + } + + return NULL; +} + BOOL is_virtual_desktop(void) { HANDLE desktop = NtUserGetThreadDesktop( GetCurrentThreadId() ); @@ -249,11 +393,13 @@ HDESK WINAPI NtUserGetThreadDesktop( DWORD thread ) BOOL WINAPI NtUserSetThreadDesktop( HDESK handle ) { BOOL ret, was_virtual_desktop = is_virtual_desktop(); + obj_locator_t locator; SERVER_START_REQ( set_thread_desktop ) { req->handle = wine_server_obj_handle( handle ); ret = !wine_server_call_err( req ); + locator = reply->locator; } SERVER_END_REQ; @@ -261,6 +407,7 @@ BOOL WINAPI NtUserSetThreadDesktop( HDESK handle ) { struct user_thread_info *thread_info = get_user_thread_info(); struct user_key_state_info *key_state_info = thread_info->key_state; + get_session_thread_data()->shared_desktop = find_shared_session_object( locator ); thread_info->client_info.top_window = 0; thread_info->client_info.msg_window = 0; if (key_state_info) key_state_info->time = 0;
1
0
0
0
Rémi Bernon : server: Return the desktop object locator in (get|set)_thread_desktop.
by Alexandre Julliard
20 Jun '24
20 Jun '24
Module: wine Branch: master Commit: 20f4c9af0f44be34b54c8c0c10b302d86303fafd URL:
https://gitlab.winehq.org/wine/wine/-/commit/20f4c9af0f44be34b54c8c0c10b302…
Author: Rémi Bernon <rbernon(a)codeweavers.com> Date: Sat Mar 16 20:41:13 2024 +0100 server: Return the desktop object locator in (get|set)_thread_desktop. --- include/wine/server_protocol.h | 14 +++++++++++--- server/file.h | 1 + server/mapping.c | 7 +++++++ server/protocol.def | 11 ++++++++++- server/request.h | 8 ++++++-- server/trace.c | 18 ++++++++++++++++-- server/winstation.c | 10 ++++++++++ tools/make_requests | 1 + 8 files changed, 62 insertions(+), 8 deletions(-) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index b75b88b956d..ec9b335b436 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -900,6 +900,12 @@ typedef volatile struct object_shm_t shm; } shared_object_t; +typedef struct +{ + object_id_t id; + mem_size_t offset; +} obj_locator_t; + @@ -3895,8 +3901,9 @@ struct get_thread_desktop_request struct get_thread_desktop_reply { struct reply_header __header; - obj_handle_t handle; - char __pad_12[4]; + obj_locator_t locator; + obj_handle_t handle; + char __pad_28[4]; }; @@ -3909,6 +3916,7 @@ struct set_thread_desktop_request struct set_thread_desktop_reply { struct reply_header __header; + obj_locator_t locator; }; @@ -6552,7 +6560,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 810 +#define SERVER_PROTOCOL_VERSION 811 /* ### protocol_version end ### */ diff --git a/server/file.h b/server/file.h index abfc2f0a2ce..89f91c52993 100644 --- a/server/file.h +++ b/server/file.h @@ -194,6 +194,7 @@ extern void set_session_mapping( struct mapping *mapping ); extern const volatile void *alloc_shared_object(void); extern void free_shared_object( const volatile void *object_shm ); +extern obj_locator_t get_shared_object_locator( const volatile void *object_shm ); #define SHARED_WRITE_BEGIN( object_shm, type ) \ do { \ diff --git a/server/mapping.c b/server/mapping.c index f77de343f4f..92eb0c9f076 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -1407,6 +1407,13 @@ void free_shared_object( const volatile void *object_shm ) list_add_tail( &session.free_objects, &object->entry ); } +obj_locator_t get_shared_object_locator( const volatile void *object_shm ) +{ + struct session_object *object = CONTAINING_RECORD( object_shm, struct session_object, obj.shm ); + obj_locator_t locator = {.offset = object->offset, .id = object->obj.id}; + return locator; +} + struct object *create_user_data_mapping( struct object *root, const struct unicode_str *name, unsigned int attr, const struct security_descriptor *sd ) { diff --git a/server/protocol.def b/server/protocol.def index de763210ac9..a832296bb30 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -916,6 +916,12 @@ typedef volatile struct object_shm_t shm; /* object shared data */ } shared_object_t; +typedef struct +{ + object_id_t id; /* object unique id, object data is valid if != 0 */ + mem_size_t offset; /* offset of the object in session shared memory */ +} obj_locator_t; + /****************************************************************/ /* Request declarations */ @@ -2813,13 +2819,16 @@ enum coords_relative @REQ(get_thread_desktop) thread_id_t tid; /* thread id */ @REPLY - obj_handle_t handle; /* handle to the desktop */ + obj_locator_t locator; /* locator for the shared session object */ + obj_handle_t handle; /* handle to the desktop */ @END /* Set the thread current desktop */ @REQ(set_thread_desktop) obj_handle_t handle; /* handle to the desktop */ +@REPLY + obj_locator_t locator; /* locator for the shared session object */ @END diff --git a/server/request.h b/server/request.h index fe323d4785a..8408c875306 100644 --- a/server/request.h +++ b/server/request.h @@ -721,6 +721,7 @@ C_ASSERT( sizeof(mem_size_t) == 8 ); C_ASSERT( sizeof(message_data_t) == 48 ); C_ASSERT( sizeof(mod_handle_t) == 8 ); C_ASSERT( sizeof(obj_handle_t) == 4 ); +C_ASSERT( sizeof(obj_locator_t) == 16 ); C_ASSERT( sizeof(object_id_t) == 8 ); C_ASSERT( sizeof(pe_image_info_t) == 88 ); C_ASSERT( sizeof(process_id_t) == 4 ); @@ -1745,10 +1746,13 @@ C_ASSERT( FIELD_OFFSET(struct close_desktop_request, handle) == 12 ); C_ASSERT( sizeof(struct close_desktop_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_thread_desktop_request, tid) == 12 ); C_ASSERT( sizeof(struct get_thread_desktop_request) == 16 ); -C_ASSERT( FIELD_OFFSET(struct get_thread_desktop_reply, handle) == 8 ); -C_ASSERT( sizeof(struct get_thread_desktop_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_desktop_reply, locator) == 8 ); +C_ASSERT( FIELD_OFFSET(struct get_thread_desktop_reply, handle) == 24 ); +C_ASSERT( sizeof(struct get_thread_desktop_reply) == 32 ); C_ASSERT( FIELD_OFFSET(struct set_thread_desktop_request, handle) == 12 ); C_ASSERT( sizeof(struct set_thread_desktop_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct set_thread_desktop_reply, locator) == 8 ); +C_ASSERT( sizeof(struct set_thread_desktop_reply) == 24 ); C_ASSERT( FIELD_OFFSET(struct enum_desktop_request, winstation) == 12 ); C_ASSERT( FIELD_OFFSET(struct enum_desktop_request, index) == 16 ); C_ASSERT( sizeof(struct enum_desktop_request) == 24 ); diff --git a/server/trace.c b/server/trace.c index 08adda28230..f19cd9c6189 100644 --- a/server/trace.c +++ b/server/trace.c @@ -467,6 +467,14 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input ) } } +static void dump_obj_locator( const char *prefix, const obj_locator_t *locator ) +{ + fprintf( stderr, "%s{", prefix ); + dump_uint64( "id=", &locator->id ); + dump_uint64( ",offset=", &locator->offset ); + fprintf( stderr, "}" ); +} + static void dump_luid( const char *prefix, const struct luid *luid ) { fprintf( stderr, "%s%d.%u", prefix, luid->high_part, luid->low_part ); @@ -3426,7 +3434,8 @@ static void dump_get_thread_desktop_request( const struct get_thread_desktop_req static void dump_get_thread_desktop_reply( const struct get_thread_desktop_reply *req ) { - fprintf( stderr, " handle=%04x", req->handle ); + dump_obj_locator( " locator=", &req->locator ); + fprintf( stderr, ", handle=%04x", req->handle ); } static void dump_set_thread_desktop_request( const struct set_thread_desktop_request *req ) @@ -3434,6 +3443,11 @@ static void dump_set_thread_desktop_request( const struct set_thread_desktop_req fprintf( stderr, " handle=%04x", req->handle ); } +static void dump_set_thread_desktop_reply( const struct set_thread_desktop_reply *req ) +{ + dump_obj_locator( " locator=", &req->locator ); +} + static void dump_enum_desktop_request( const struct enum_desktop_request *req ) { fprintf( stderr, " winstation=%04x", req->winstation ); @@ -5101,7 +5115,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { NULL, NULL, (dump_func)dump_get_thread_desktop_reply, - NULL, + (dump_func)dump_set_thread_desktop_reply, (dump_func)dump_enum_desktop_reply, (dump_func)dump_set_user_object_info_reply, (dump_func)dump_register_hotkey_reply, diff --git a/server/winstation.c b/server/winstation.c index 270720437b0..8136c473815 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -742,10 +742,19 @@ DECL_HANDLER(close_desktop) /* get the thread current desktop */ DECL_HANDLER(get_thread_desktop) { + struct desktop *desktop; struct thread *thread; if (!(thread = get_thread_from_id( req->tid ))) return; reply->handle = thread->desktop; + + if (!(desktop = get_thread_desktop( thread, 0 ))) clear_error(); + else + { + if (desktop->shared) reply->locator = get_shared_object_locator( desktop->shared ); + release_object( desktop ); + } + release_object( thread ); } @@ -788,6 +797,7 @@ DECL_HANDLER(set_thread_desktop) if (old_desktop) remove_desktop_thread( old_desktop, current ); add_desktop_thread( new_desktop, current ); } + reply->locator = get_shared_object_locator( new_desktop->shared ); } if (!current->process->desktop) diff --git a/tools/make_requests b/tools/make_requests index b20b53096ca..36254faec40 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -53,6 +53,7 @@ my %formats = "generic_map_t" => [ 16, 4, "&dump_generic_map" ], "ioctl_code_t" => [ 4, 4, "&dump_ioctl_code" ], "hw_input_t" => [ 40, 8, "&dump_hw_input" ], + "obj_locator_t" => [ 16, 8, "&dump_obj_locator" ], # varargs-only structures "apc_call_t" => [ 64, 8 ], "context_t" => [ 1728, 8 ],
1
0
0
0
← Newer
1
...
20
21
22
23
24
25
26
...
62
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Results per page:
10
25
50
100
200