[PATCH v2] msscript.ocx: Supply a stub ServiceProvider to InvokeEx in run_procedure.

Gabriel Ivăncescu gabrielopcode at gmail.com
Thu Sep 10 08:32:59 CDT 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

I don't know what Windows supplies this object for (I tried all the SIDs in
Wine's headers and none pass except SID_GetCaller), but this does "match"
Windows behavior. More importantly, should an app request some service,
we can now see it in the FIXME and implement it accordingly.

 dlls/msscript.ocx/msscript.c       | 47 +++++++++++++++++++++++++++++-
 dlls/msscript.ocx/tests/msscript.c | 30 +++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index ed17be9..70dc05f 100644
--- a/dlls/msscript.ocx/msscript.c
+++ b/dlls/msscript.ocx/msscript.c
@@ -434,6 +434,51 @@ static HRESULT parse_script_text(ScriptModule *module, BSTR script_text, DWORD f
     return hr;
 }
 
+static HRESULT WINAPI sp_caller_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj)
+{
+    if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IServiceProvider, riid))
+        *obj = iface;
+    else
+    {
+        FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
+        *obj = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*obj);
+    return S_OK;
+}
+
+static ULONG WINAPI sp_caller_AddRef(IServiceProvider *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI sp_caller_Release(IServiceProvider *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI sp_caller_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
+{
+    FIXME("(%p)->(%s %s %p): semi-stub\n", iface, debugstr_guid(service), debugstr_guid(riid), obj);
+
+    *obj = NULL;
+    if (IsEqualGUID(&SID_GetCaller, service))
+        return S_OK;
+
+    return E_NOINTERFACE;
+}
+
+static const IServiceProviderVtbl sp_caller_vtbl = {
+    sp_caller_QueryInterface,
+    sp_caller_AddRef,
+    sp_caller_Release,
+    sp_caller_QueryService
+};
+
+static IServiceProvider sp_caller = { &sp_caller_vtbl };
+
 static HRESULT run_procedure(ScriptModule *module, BSTR procedure_name, SAFEARRAY *args, VARIANT *res)
 {
     IDispatchEx *dispex;
@@ -475,7 +520,7 @@ static HRESULT run_procedure(ScriptModule *module, BSTR procedure_name, SAFEARRA
         else
         {
             hr = IDispatchEx_InvokeEx(dispex, dispid, LOCALE_USER_DEFAULT,
-                                      DISPATCH_METHOD, &dp, res, NULL, NULL);
+                                      DISPATCH_METHOD, &dp, res, NULL, &sp_caller);
             IDispatchEx_Release(dispex);
         }
     }
diff --git a/dlls/msscript.ocx/tests/msscript.c b/dlls/msscript.ocx/tests/msscript.c
index a6ec099..4f43764 100644
--- a/dlls/msscript.ocx/tests/msscript.c
+++ b/dlls/msscript.ocx/tests/msscript.c
@@ -673,6 +673,10 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags,
         DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
 {
+    IServiceProvider *sp;
+    IUnknown *unk;
+    HRESULT hr;
+
     CHECK_EXPECT(InvokeEx);
     ok(lcid == LOCALE_USER_DEFAULT, "unexpected lcid %u.\n", lcid);
     ok(wFlags == DISPATCH_METHOD, "unexpected wFlags %u.\n", wFlags);
@@ -690,6 +694,32 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             "unexpected second parameter V_VT = %d, V_I4 = %d.\n",
             V_VT(pdp->rgvarg), V_I4(pdp->rgvarg));
     }
+    ok(!!pspCaller, "unexpected NULL pspCaller.\n");
+
+    hr = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp);
+    ok(hr == S_OK, "Failed to retrieve IID_IServiceProvider from script site: 0x%08x.\n", hr);
+    ok(sp != pspCaller, "Same IServiceProvider objects.\n");
+    IServiceProvider_Release(sp);
+
+    hr = IServiceProvider_QueryInterface(pspCaller, &IID_IActiveScriptSite, (void**)&unk);
+    ok(hr == E_NOINTERFACE, "QueryInterface IActiveScriptSite returned: 0x%08x.\n", hr);
+
+    unk = (IUnknown*)0xdeadbeef;
+    hr = IServiceProvider_QueryService(pspCaller, &SID_GetCaller, NULL, (void**)&unk);
+    ok(hr == S_OK, "QueryService failed: 0x%08x.\n", hr);
+    ok(!unk, "unexpected object returned %p.\n", unk);
+    unk = (IUnknown*)0xdeadbeef;
+    hr = IServiceProvider_QueryService(pspCaller, &SID_GetCaller, &IID_IUnknown, (void**)&unk);
+    ok(hr == S_OK, "QueryService failed: 0x%08x.\n", hr);
+    ok(!unk, "unexpected object returned %p.\n", unk);
+    sp = (IServiceProvider*)0xdeadbeef;
+    hr = IServiceProvider_QueryService(pspCaller, &SID_GetCaller, &IID_IServiceProvider, (void**)&sp);
+    ok(hr == S_OK, "QueryService failed: 0x%08x.\n", hr);
+    ok(!sp, "unexpected object returned %p.\n", sp);
+    unk = (IUnknown*)0xdeadbeef;
+    hr = IServiceProvider_QueryService(pspCaller, &SID_VariantConversion, &IID_IVariantChangeType, (void**)&unk);
+    ok(hr == E_NOINTERFACE, "QueryService returned: 0x%08x.\n", hr);
+    ok(!unk, "unexpected object returned %p.\n", unk);
 
     V_VT(pvarRes) = VT_I2;
     V_I2(pvarRes) = 42;
-- 
2.21.0




More information about the wine-devel mailing list