From fdb304ff1444a898fd81f12961c3006f4800ca32 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Thu, 8 Jul 2021 03:34:21 +0300 Subject: [PATCH] mshtml: Export requestAnimationFrame() through a private interface. Signed-off-by: Paul Gofman Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/mshtml/dispex.c | 31 ++++++++- dlls/mshtml/htmlwindow.c | 126 +++++++++++++++++++++++++++-------- dlls/mshtml/mshtml_private.h | 6 ++ dlls/mshtml/mshtml_private_iface.idl | 18 +++++ 4 files changed, 149 insertions(+), 32 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 6d248691d6b..c7588006295 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -111,7 +111,7 @@ struct dispex_dynamic_data_t { #define FDEX_VERSION_MASK 0xf0000000 -static ITypeLib *typelib; +static ITypeLib *typelib, *typelib_private; static ITypeInfo *typeinfos[LAST_tid]; static struct list dispex_data_list = LIST_INIT(dispex_data_list); @@ -119,14 +119,18 @@ static REFIID tid_ids[] = { #define XIID(iface) &IID_ ## iface, #define XDIID(iface) &DIID_ ## iface, TID_LIST + NULL, +PRIVATE_TID_LIST #undef XIID #undef XDIID }; static HRESULT load_typelib(void) { + WCHAR module_path[MAX_PATH + 3]; HRESULT hres; ITypeLib *tl; + DWORD len; hres = LoadRegTypeLib(&LIBID_MSHTML, 4, 0, LOCALE_SYSTEM_DEFAULT, &tl); if(FAILED(hres)) { @@ -136,7 +140,25 @@ static HRESULT load_typelib(void) if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) ITypeLib_Release(tl); - return hres; + + len = GetModuleFileNameW(hInst, module_path, MAX_PATH + 1); + if (!len || len == MAX_PATH + 1) + { + ERR("Could not get module file name, len %u.\n", len); + return E_FAIL; + } + lstrcatW(module_path, L"\\1"); + + hres = LoadTypeLibEx(module_path, REGKIND_NONE, &tl); + if(FAILED(hres)) { + ERR("LoadTypeLibEx failed for private typelib: %08x\n", hres); + return hres; + } + + if(InterlockedCompareExchangePointer((void**)&typelib_private, tl, NULL)) + ITypeLib_Release(tl); + + return S_OK; } static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) @@ -151,7 +173,7 @@ static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo) if(!typeinfos[tid]) { ITypeInfo *ti; - hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); + hres = ITypeLib_GetTypeInfoOfGuid(tid > LAST_public_tid ? typelib_private : typelib, tid_ids[tid], &ti); if(FAILED(hres)) { ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_mshtml_guid(tid_ids[tid]), hres); return hres; @@ -197,6 +219,7 @@ void release_typelib(void) ITypeInfo_Release(typeinfos[i]); ITypeLib_Release(typelib); + ITypeLib_Release(typelib_private); DeleteCriticalSection(&cs_dispex_static_data); } @@ -210,6 +233,8 @@ HRESULT get_class_typeinfo(const CLSID *clsid, ITypeInfo **typeinfo) return hres; hres = ITypeLib_GetTypeInfoOfGuid(typelib, clsid, typeinfo); + if (FAILED(hres)) + hres = ITypeLib_GetTypeInfoOfGuid(typelib_private, clsid, typeinfo); if(FAILED(hres)) ERR("GetTypeInfoOfGuid failed: %08x\n", hres); return hres; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 4196d1f45ad..dce329d9ec6 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -189,6 +189,8 @@ static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID rii *ppv = &This->IProvideMultipleClassInfo_iface; }else if(IsEqualGUID(&IID_IProvideMultipleClassInfo, riid)) { *ppv = &This->IProvideMultipleClassInfo_iface; + }else if(IsEqualGUID(&IID_IWineHTMLWindowPrivate, riid)) { + *ppv = &This->IWineHTMLWindowPrivate_iface; }else if(IsEqualGUID(&IID_IMarshal, riid)) { *ppv = NULL; FIXME("(%p)->(IID_IMarshal %p)\n", This, ppv); @@ -3033,6 +3035,97 @@ static const IProvideMultipleClassInfoVtbl ProvideMultipleClassInfoVtbl = { ProvideMultipleClassInfo_GetInfoOfIndex }; +static inline HTMLWindow *impl_from_IWineHTMLWindowPrivateVtbl(IWineHTMLWindowPrivate *iface) +{ + return CONTAINING_RECORD(iface, HTMLWindow, IWineHTMLWindowPrivate_iface); +} + +static HRESULT WINAPI window_private_QueryInterface(IWineHTMLWindowPrivate *iface, + REFIID riid, void **ppv) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + + return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv); +} + +static ULONG WINAPI window_private_AddRef(IWineHTMLWindowPrivate *iface) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + + return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface); +} + +static ULONG WINAPI window_private_Release(IWineHTMLWindowPrivate *iface) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + + return IHTMLWindow2_Release(&This->IHTMLWindow2_iface); +} + +static HRESULT WINAPI window_private_GetTypeInfoCount(IWineHTMLWindowPrivate *iface, UINT *pctinfo) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + + return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI window_private_GetTypeInfo(IWineHTMLWindowPrivate *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + + return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI window_private_GetIDsOfNames(IWineHTMLWindowPrivate *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + + return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, + rgDispId); +} + +static HRESULT WINAPI window_private_Invoke(IWineHTMLWindowPrivate *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + + return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI window_private_requestAnimationFrame(IWineHTMLWindowPrivate *iface, + VARIANT *expr, VARIANT *timer_id) +{ + HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); + HRESULT hres; + LONG r; + + FIXME("iface %p, expr %p, timer_id %p semi-stub.\n", iface, expr, timer_id); + + hres = window_set_timer(This->inner_window, expr, 50, NULL, TIMER_ANIMATION_FRAME, &r); + if(SUCCEEDED(hres) && timer_id) { + V_VT(timer_id) = VT_I4; + V_I4(timer_id) = r; + } + + return hres; +} + +static const IWineHTMLWindowPrivateVtbl WineHTMLWindowPrivateVtbl = { + window_private_QueryInterface, + window_private_AddRef, + window_private_Release, + window_private_GetTypeInfoCount, + window_private_GetTypeInfo, + window_private_GetIDsOfNames, + window_private_Invoke, + window_private_requestAnimationFrame, +}; + static inline HTMLWindow *impl_from_IDispatchEx(IDispatchEx *iface) { return CONTAINING_RECORD(iface, HTMLWindow, IDispatchEx_iface); @@ -3176,9 +3269,6 @@ HRESULT search_window_props(HTMLInnerWindow *This, BSTR bstrName, DWORD grfdex, return DISP_E_UNKNOWNNAME; } -/* DISPIDs not exposed by interfaces */ -#define DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME 1300 - static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { HTMLWindow *This = impl_from_IDispatchEx(iface); @@ -3195,13 +3285,6 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, if(hres != DISP_E_UNKNOWNNAME) return hres; - if(dispex_compat_mode(&window->event_target.dispex) >= COMPAT_MODE_IE10 && - !wcscmp(bstrName, L"requestAnimationFrame")) { - TRACE("requestAnimationFrame\n"); - *pid = DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME; - return S_OK; - } - if(This->outer_window) { HTMLOuterWindow *frame; @@ -3288,25 +3371,6 @@ static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID return IDispatchEx_InvokeEx(&window->event_target.dispex.IDispatchEx_iface, id, lcid, wFlags, &dp, pvarRes, pei, pspCaller); } - case DISPID_IHTMLWINDOW_IE10_REQUESTANIMATIONFRAME: { - HRESULT hres; - LONG r; - - FIXME("requestAnimationFrame: semi-stub\n"); - - if(!(wFlags & DISPATCH_METHOD) || pdp->cArgs != 1 || pdp->cNamedArgs) { - FIXME("unsupported args\n"); - return E_INVALIDARG; - } - - hres = window_set_timer(window, pdp->rgvarg, 50, NULL, TIMER_ANIMATION_FRAME, &r); - if(SUCCEEDED(hres) && pvarRes) { - V_VT(pvarRes) = VT_I4; - V_I4(pvarRes) = r; - } - - return hres; - } } return IDispatchEx_InvokeEx(&window->event_target.dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); @@ -3566,6 +3630,9 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa { if(compat_mode >= COMPAT_MODE_IE9) dispex_info_add_interface(info, IHTMLWindow7_tid, NULL); + if(compat_mode >= COMPAT_MODE_IE10) + dispex_info_add_interface(info, IWineHTMLWindowPrivate_tid, NULL); + dispex_info_add_interface(info, IHTMLWindow5_tid, NULL); EventTarget_init_dispex_info(info, compat_mode); } @@ -3627,6 +3694,7 @@ static void *alloc_window(size_t size) window->ITravelLogClient_iface.lpVtbl = &TravelLogClientVtbl; window->IObjectIdentity_iface.lpVtbl = &ObjectIdentityVtbl; window->IProvideMultipleClassInfo_iface.lpVtbl = &ProvideMultipleClassInfoVtbl; + window->IWineHTMLWindowPrivate_iface.lpVtbl = &WineHTMLWindowPrivateVtbl; window->ref = 1; return window; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 6228cf1298d..08b4df86e31 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -272,10 +272,15 @@ typedef struct EventTarget EventTarget; XIID(ISVGTSpanElement) \ XIID(ISVGTextContentElement) +#define PRIVATE_TID_LIST \ + XIID(IWineHTMLWindowPrivate) + typedef enum { #define XIID(iface) iface ## _tid, #define XDIID(iface) iface ## _tid, TID_LIST + LAST_public_tid, +PRIVATE_TID_LIST #undef XIID #undef XDIID LAST_tid @@ -485,6 +490,7 @@ struct HTMLWindow { ITravelLogClient ITravelLogClient_iface; IObjectIdentity IObjectIdentity_iface; IProvideMultipleClassInfo IProvideMultipleClassInfo_iface; + IWineHTMLWindowPrivate IWineHTMLWindowPrivate_iface; LONG ref; diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 5a01c6c1b27..c147b2445dc 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -18,6 +18,8 @@ #pragma makedep typelib +import "ocidl.idl"; + [ version(1.0), hidden, @@ -25,4 +27,20 @@ ] library MSHTML_private { + +importlib("stdole2.tlb"); + +[ + odl, + oleautomation, + dual, + hidden, + uuid(1b5939fc-8f84-43f3-8d89-f9a92069fad7) +] +interface IWineHTMLWindowPrivate : IDispatch +{ + [id(1)] + HRESULT requestAnimationFrame([in] VARIANT *expr, [retval, out] VARIANT *timer_id); +} + } /* library MSHTML_private */ -- 2.11.4.GIT