[PATCH v4 3/4] mshtml: Export requestAnimationFrame() through a private interface.

Paul Gofman pgofman at codeweavers.com
Wed Jul 7 19:34:21 CDT 2021


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
v4:
    - split off the private interface creation and put requestAnimationFrame there;
    - use GetModuleFileName() instead of hardcoding "mshtml.dll";
    - remove unneeded dispinterfaces;
    - renamed IWineConsoleGetter to IWineHTMLWindowPrivate;


 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.31.1




More information about the wine-devel mailing list