Jacek Caban : jscript: Call SetSite on created ActiveX object.

Alexandre Julliard julliard at winehq.org
Wed Oct 7 09:46:04 CDT 2009


Module: wine
Branch: master
Commit: 06f26f53f73636feebd97e6c94c6ca86b17d6336
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=06f26f53f73636feebd97e6c94c6ca86b17d6336

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Oct  6 21:23:14 2009 +0200

jscript: Call SetSite on created ActiveX object.

---

 dlls/jscript/activex.c       |   13 +++++-
 dlls/jscript/jscript.c       |   99 ++++++++++++++++++++++++++++++++++++++++++
 dlls/jscript/jscript.h       |    2 +
 dlls/jscript/tests/activex.c |   91 +++++++++++++++++++++++++++++++++++++-
 4 files changed, 202 insertions(+), 3 deletions(-)

diff --git a/dlls/jscript/activex.c b/dlls/jscript/activex.c
index 027a2e2..8af4eb7 100644
--- a/dlls/jscript/activex.c
+++ b/dlls/jscript/activex.c
@@ -117,8 +117,19 @@ static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid)
 
     hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site);
     if(SUCCEEDED(hres)) {
-        FIXME("Set object site\n");
+        IUnknown *ax_site;
+
+        ax_site = create_ax_site(ctx);
+        if(ax_site) {
+            hres = IObjectWithSite_SetSite(obj_site, ax_site);
+            IUnknown_Release(ax_site);
+        }
         IObjectWithSite_Release(obj_site);
+        if(!ax_site || FAILED(hres)) {
+            IObjectWithSite_Release(obj_site);
+            IUnknown_Release(obj);
+            return NULL;
+        }
     }
 
     return obj;
diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c
index 90a5b47..eb41835 100644
--- a/dlls/jscript/jscript.c
+++ b/dlls/jscript/jscript.c
@@ -159,6 +159,105 @@ static HRESULT set_ctx_site(JScript *This)
     return S_OK;
 }
 
+typedef struct {
+    const IServiceProviderVtbl *lpIServiceProviderVtbl;
+
+    LONG ref;
+
+    IServiceProvider *sp;
+} AXSite;
+
+#define SERVPROV(x)  ((IServiceProvider*) &(x)->lpIServiceProviderVtbl)
+
+#define SERVPROV_THIS(iface) DEFINE_THIS(AXSite, IServiceProvider, iface)
+
+static HRESULT WINAPI AXSite_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
+{
+    AXSite *This = SERVPROV_THIS(iface);
+
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = SERVPROV(This);
+    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
+        TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
+        *ppv = SERVPROV(This);
+    }else {
+        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI AXSite_AddRef(IServiceProvider *iface)
+{
+    AXSite *This = SERVPROV_THIS(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI AXSite_Release(IServiceProvider *iface)
+{
+    AXSite *This = SERVPROV_THIS(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref)
+        heap_free(This);
+
+    return ref;
+}
+
+static HRESULT WINAPI AXSite_QueryService(IServiceProvider *iface,
+        REFGUID guidService, REFIID riid, void **ppv)
+{
+    AXSite *This = SERVPROV_THIS(iface);
+
+    TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
+
+    return IServiceProvider_QueryService(This->sp, guidService, riid, ppv);
+}
+
+#undef SERVPROV_THIS
+
+static IServiceProviderVtbl AXSiteVtbl = {
+    AXSite_QueryInterface,
+    AXSite_AddRef,
+    AXSite_Release,
+    AXSite_QueryService
+};
+
+IUnknown *create_ax_site(script_ctx_t *ctx)
+{
+    IServiceProvider *sp;
+    AXSite *ret;
+    HRESULT hres;
+
+    hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
+    if(FAILED(hres)) {
+        ERR("Could not get IServiceProvider iface: %08x\n", hres);
+        return NULL;
+    }
+
+    ret = heap_alloc(sizeof(AXSite));
+    if(!ret) {
+        IServiceProvider_Release(sp);
+        return NULL;
+    }
+
+    ret->lpIServiceProviderVtbl = &AXSiteVtbl;
+    ret->ref = 1;
+    ret->sp = sp;
+
+    return (IUnknown*)SERVPROV(ret);
+}
+
 #define ACTSCRIPT_THIS(iface) DEFINE_THIS(JScript, IActiveScript, iface)
 
 static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 4451669..cde1e1b 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -309,6 +309,8 @@ HRESULT create_object_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
 HRESULT create_regexp_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
 HRESULT create_string_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
 
+IUnknown *create_ax_site(script_ctx_t*);
+
 typedef struct {
     const WCHAR *str;
     DWORD len;
diff --git a/dlls/jscript/tests/activex.c b/dlls/jscript/tests/activex.c
index cd7b5a0..4826910 100644
--- a/dlls/jscript/tests/activex.c
+++ b/dlls/jscript/tests/activex.c
@@ -67,6 +67,7 @@ DEFINE_EXPECT(reportSuccess);
 DEFINE_EXPECT(Host_QS_SecMgr);
 DEFINE_EXPECT(Caller_QS_SecMgr);
 DEFINE_EXPECT(QI_IObjectWithSite);
+DEFINE_EXPECT(SetSite);
 
 static const WCHAR testW[] = {'t','e','s','t',0};
 
@@ -78,6 +79,7 @@ static HRESULT QueryCustomPolicy_hres;
 static DWORD QueryCustomPolicy_psize;
 static DWORD QueryCustomPolicy_policy;
 static HRESULT QI_IDispatch_hres;
+static HRESULT SetSite_hres;
 
 #define TESTOBJ_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80646}"
 
@@ -123,6 +125,56 @@ static int strcmp_wa(LPCWSTR strw, const char *stra)
     return lstrcmpA(buf, stra);
 }
 
+static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite)
+{
+    IServiceProvider *sp;
+    HRESULT hres;
+
+
+    CHECK_EXPECT(SetSite);
+    ok(pUnkSite != NULL, "pUnkSite == NULL\n");
+
+    hres = IUnknown_QueryInterface(pUnkSite, &IID_IServiceProvider, (void**)&sp);
+    ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
+    IServiceProvider_Release(sp);
+
+    return SetSite_hres;
+}
+
+static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static const IObjectWithSiteVtbl ObjectWithSiteVtbl = {
+    ObjectWithSite_QueryInterface,
+    ObjectWithSite_AddRef,
+    ObjectWithSite_Release,
+    ObjectWithSite_SetSite,
+    ObjectWithSite_GetSite
+};
+
+static IObjectWithSite ObjectWithSite = { &ObjectWithSiteVtbl };
+
+static IObjectWithSite *object_with_site;
+
 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
 {
     *ppv = NULL;
@@ -135,12 +187,12 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid,
         *ppv = iface;
     }else if(IsEqualGUID(&IID_IObjectWithSite, riid)) {
         CHECK_EXPECT(QI_IObjectWithSite);
-        return E_NOINTERFACE;
+        *ppv = object_with_site;
     }else {
         return E_NOINTERFACE;
     }
 
-    return S_OK;
+    return *ppv ? S_OK : E_NOINTERFACE;
 }
 
 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
@@ -663,6 +715,7 @@ static IActiveScriptParse *create_script(void)
     QueryCustomPolicy_psize = sizeof(DWORD);
     QueryCustomPolicy_policy = URLPOLICY_ALLOW;
     QI_IDispatch_hres = S_OK;
+    SetSite_hres = S_OK;
 
     hres = CoCreateInstance(&CLSID_JScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
             &IID_IActiveScript, (void**)&script);
@@ -925,6 +978,40 @@ static void test_ActiveXObject(void)
     CHECK_CALLED(QueryCustomPolicy);
 
     IUnknown_Release(parser);
+
+    parser = create_script();
+    object_with_site = &ObjectWithSite;
+
+    SET_EXPECT(Host_QS_SecMgr);
+    SET_EXPECT(ProcessUrlAction);
+    SET_EXPECT(CreateInstance);
+    SET_EXPECT(QueryCustomPolicy);
+    SET_EXPECT(QI_IObjectWithSite);
+    SET_EXPECT(SetSite);
+    SET_EXPECT(reportSuccess);
+    parse_script_a(parser, "(new ActiveXObject('Wine.Test')).reportSuccess();");
+    CHECK_CALLED(Host_QS_SecMgr);
+    CHECK_CALLED(ProcessUrlAction);
+    CHECK_CALLED(CreateInstance);
+    CHECK_CALLED(QueryCustomPolicy);
+    CHECK_CALLED(QI_IObjectWithSite);
+    CHECK_CALLED(SetSite);
+    CHECK_CALLED(reportSuccess);
+
+    SetSite_hres = E_FAIL;
+    SET_EXPECT(ProcessUrlAction);
+    SET_EXPECT(CreateInstance);
+    SET_EXPECT(QueryCustomPolicy);
+    SET_EXPECT(QI_IObjectWithSite);
+    SET_EXPECT(SetSite);
+    parse_script_a(parser, "testException(function() { new ActiveXObject('Wine.Test'); }, 'Error', -2146827859);");
+    CHECK_CALLED(ProcessUrlAction);
+    CHECK_CALLED(CreateInstance);
+    CHECK_CALLED(QueryCustomPolicy);
+    CHECK_CALLED(QI_IObjectWithSite);
+    CHECK_CALLED(SetSite);
+
+    IUnknown_Release(parser);
 }
 
 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)




More information about the wine-cvs mailing list