From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Tested in next patch, as we'll need the command target for the script site. --- dlls/mshtml/htmlscript.h | 1 + dlls/mshtml/htmlwindow.c | 6 +++++- dlls/mshtml/script.c | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlscript.h b/dlls/mshtml/htmlscript.h index f8760c134fe..837e9a4df62 100644 --- a/dlls/mshtml/htmlscript.h +++ b/dlls/mshtml/htmlscript.h @@ -39,6 +39,7 @@ HRESULT script_elem_from_nsscript(nsIDOMHTMLScriptElement*,HTMLScriptElement**); void bind_event_scripts(HTMLDocumentNode*); HRESULT load_script(HTMLScriptElement*,const WCHAR*,BOOL);
+void move_script_hosts(HTMLInnerWindow*,HTMLInnerWindow*); void release_script_hosts(HTMLInnerWindow*); void connect_scripts(HTMLInnerWindow*); void doc_insert_script(HTMLInnerWindow*,HTMLScriptElement*,BOOL); diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index fa99c453989..dd6c0bc5c5e 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -4547,8 +4547,12 @@ HRESULT update_window_doc(HTMLInnerWindow *window) return S_OK; }
- if(outer_window->base.inner_window) + if(outer_window->base.inner_window) { + if(!outer_window->base.inner_window->navigation_start_time && outer_window->browser->doc) + move_script_hosts(outer_window->base.inner_window, window); + detach_inner_window(outer_window->base.inner_window); + } outer_window->base.inner_window = window; outer_window->pending_window = NULL;
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index cad0f17671a..b3eb99afa02 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -1780,6 +1780,22 @@ void update_browser_script_mode(GeckoBrowser *browser, IUri *uri) ERR("JavaScript setup failed: %08lx\n", nsres); }
+void move_script_hosts(HTMLInnerWindow *window, HTMLInnerWindow *new_window) +{ + ScriptHost *iter, *iter2; + + if(list_empty(&window->script_hosts)) + return; + + LIST_FOR_EACH_ENTRY_SAFE(iter, iter2, &window->script_hosts, ScriptHost, entry) { + iter->window = new_window; + list_remove(&iter->entry); + list_add_tail(&new_window->script_hosts, &iter->entry); + } + + lock_document_mode(new_window->doc); +} + void release_script_hosts(HTMLInnerWindow *window) { script_queue_entry_t *queue_iter;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
With IOleCommandTarget stub, since it's the interface used.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlscript.h | 3 + dlls/mshtml/script.c | 78 ++++++++++++ dlls/mshtml/service.c | 16 +++ dlls/mshtml/tests/events.c | 31 ++++- dlls/mshtml/tests/htmldoc.c | 52 ++++++++ dlls/mshtml/tests/script.c | 228 ++++++++++++++++++++++++++++++++++-- 6 files changed, 397 insertions(+), 11 deletions(-)
diff --git a/dlls/mshtml/htmlscript.h b/dlls/mshtml/htmlscript.h index 837e9a4df62..0f494b23599 100644 --- a/dlls/mshtml/htmlscript.h +++ b/dlls/mshtml/htmlscript.h @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "activscp.h" + struct HTMLScriptElement { HTMLElement element;
@@ -48,3 +50,4 @@ HRESULT exec_script(HTMLInnerWindow*,const WCHAR*,const WCHAR*,VARIANT*); void update_browser_script_mode(GeckoBrowser*,IUri*); BOOL find_global_prop(HTMLInnerWindow*,BSTR,DWORD,ScriptHost**,DISPID*); IDispatch *get_script_disp(ScriptHost*); +IActiveScriptSite *get_first_script_site(HTMLInnerWindow*); diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index b3eb99afa02..1af5167efaa 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -74,6 +74,7 @@ struct ScriptHost { IActiveScriptSiteUIControl IActiveScriptSiteUIControl_iface; IActiveScriptSiteDebug IActiveScriptSiteDebug_iface; IServiceProvider IServiceProvider_iface; + IOleCommandTarget IOleCommandTarget_iface;
LONG ref;
@@ -308,6 +309,9 @@ static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv); *ppv = &This->IServiceProvider_iface; + }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) { + TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This, ppv); + *ppv = &This->IOleCommandTarget_iface; }else if(IsEqualGUID(&IID_ICanHandleException, riid)) { TRACE("(%p)->(IID_ICanHandleException not supported %p)\n", This, ppv); return E_NOINTERFACE; @@ -675,6 +679,18 @@ static HRESULT WINAPI ASServiceProvider_QueryService(IServiceProvider *iface, RE { ScriptHost *This = impl_from_IServiceProvider(iface);
+ if(IsEqualGUID(&IID_IActiveScriptSite, guidService)) { + ScriptHost *script_host = This; + + TRACE("(%p)->(IID_IActiveScriptSite)\n", This); + + /* Use first script site if available */ + if(This->window && !list_empty(&This->window->script_hosts)) + script_host = LIST_ENTRY(list_head(&This->window->script_hosts), ScriptHost, entry); + + return IActiveScriptSite_QueryInterface(&script_host->IActiveScriptSite_iface, riid, ppv); + } + if(IsEqualGUID(&SID_SInternetHostSecurityManager, guidService)) { TRACE("(%p)->(SID_SInternetHostSecurityManager)\n", This);
@@ -705,6 +721,57 @@ static const IServiceProviderVtbl ASServiceProviderVtbl = { ASServiceProvider_QueryService };
+static inline ScriptHost *impl_from_IOleCommandTarget(IOleCommandTarget *iface) +{ + return CONTAINING_RECORD(iface, ScriptHost, IOleCommandTarget_iface); +} + +static HRESULT WINAPI OleCommandTarget_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppv) +{ + ScriptHost *This = impl_from_IOleCommandTarget(iface); + return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, ppv); +} + +static ULONG WINAPI OleCommandTarget_AddRef(IOleCommandTarget *iface) +{ + ScriptHost *This = impl_from_IOleCommandTarget(iface); + return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface); +} + +static ULONG WINAPI OleCommandTarget_Release(IOleCommandTarget *iface) +{ + ScriptHost *This = impl_from_IOleCommandTarget(iface); + return IActiveScriptSite_Release(&This->IActiveScriptSite_iface); +} + +static HRESULT WINAPI OleCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup, + ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) +{ + ScriptHost *This = impl_from_IOleCommandTarget(iface); + + FIXME("(%p)->(%s %ld %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText); + + return E_NOTIMPL; +} + +static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup, + DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) +{ + ScriptHost *This = impl_from_IOleCommandTarget(iface); + + FIXME("(%p)->(%s %ld %ld %s %p)\n", This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, wine_dbgstr_variant(pvaIn), pvaOut); + + return E_NOTIMPL; +} + +static const IOleCommandTargetVtbl OleCommandTargetVtbl = { + OleCommandTarget_QueryInterface, + OleCommandTarget_AddRef, + OleCommandTarget_Release, + OleCommandTarget_QueryStatus, + OleCommandTarget_Exec +}; + static ScriptHost *create_script_host(HTMLInnerWindow *window, const GUID *guid) { IActiveScript *script; @@ -721,6 +788,7 @@ static ScriptHost *create_script_host(HTMLInnerWindow *window, const GUID *guid) ret->IActiveScriptSiteUIControl_iface.lpVtbl = &ActiveScriptSiteUIControlVtbl; ret->IActiveScriptSiteDebug_iface.lpVtbl = &ActiveScriptSiteDebugVtbl; ret->IServiceProvider_iface.lpVtbl = &ASServiceProviderVtbl; + ret->IOleCommandTarget_iface.lpVtbl = &OleCommandTargetVtbl; ret->ref = 1; ret->window = window; ret->script_state = SCRIPTSTATE_UNINITIALIZED; @@ -1474,6 +1542,16 @@ IDispatch *get_script_disp(ScriptHost *script_host) return disp; }
+IActiveScriptSite *get_first_script_site(HTMLInnerWindow *window) +{ + if(list_empty(&window->script_hosts)) { + ScriptHost *script_host = create_script_host(window, &CLSID_JScript); + if(!script_host) + return NULL; + } + return &LIST_ENTRY(list_head(&window->script_hosts), ScriptHost, entry)->IActiveScriptSite_iface; +} + static EventTarget *find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *script_elem) { EventTarget *event_target = NULL; diff --git a/dlls/mshtml/service.c b/dlls/mshtml/service.c index 1f440b846e8..f7a4003462c 100644 --- a/dlls/mshtml/service.c +++ b/dlls/mshtml/service.c @@ -29,6 +29,7 @@ #include "wine/debug.h"
#include "mshtml_private.h" +#include "htmlscript.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
@@ -360,6 +361,21 @@ static HRESULT WINAPI DocNodeServiceProvider_QueryService(IServiceProvider *ifac { HTMLDocumentNode *This = HTMLDocumentNode_from_IServiceProvider(iface);
+ if(IsEqualGUID(&IID_IActiveScriptSite, guidService)) { + IActiveScriptSite *site; + + TRACE("IID_IActiveScriptSite\n"); + + if(!This->window) { + FIXME("No window\n"); + return E_NOTIMPL; + } + + if(!(site = get_first_script_site(This->window))) + return E_OUTOFMEMORY; + return IActiveScriptSite_QueryInterface(site, riid, ppv); + } + if(IsEqualGUID(&SID_SContainerDispatch, guidService)) { TRACE("SID_SContainerDispatch\n"); return IHTMLDocument2_QueryInterface(&This->IHTMLDocument2_iface, riid, ppv); diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 606cbbc74ce..bea5e1598a8 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -35,6 +35,8 @@ #include "shdeprecated.h" #include "dispex.h"
+extern const IID IID_IActiveScriptSite; + #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@@ -3398,12 +3400,15 @@ static void test_doc_obj(IHTMLDocument2 *doc) IHTMLPerformance *perf, *perf2; IOmHistory *history, *history2; IHTMLScreen *screen, *screen2; + IOleCommandTarget *cmdtarget; IHTMLWindow2 *self, *window2; IEventTarget *event_target; + IUnknown *site, *site2; DISPPARAMS dp = { 0 }; IHTMLWindow7 *window7; IHTMLWindow6 *window6; IHTMLWindow5 *window5; + IServiceProvider *sp; IDispatchEx *dispex; IHTMLElement *body; VARIANT res, arg; @@ -3565,6 +3570,16 @@ static void test_doc_obj(IHTMLDocument2 *doc) ok(hres == S_OK, "get_self failed: %08lx\n", hres); ok(self != NULL, "self == NULL\n");
+ /* And script sites */ + hres = IHTMLDocument2_QueryInterface(doc_node, &IID_IServiceProvider, (void**)&sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == S_OK, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) failed: %08lx\n", hres); + hres = IOleCommandTarget_QueryInterface(cmdtarget, &IID_IActiveScriptSite, (void**)&site); + ok(hres == S_OK, "Command Target QI for IActiveScriptSite failed: %08lx\n", hres); + IOleCommandTarget_Release(cmdtarget); + IServiceProvider_Release(sp); + /* Add props to location, since it gets lost on navigation, despite being same object */ bstr = SysAllocString(L"wineTestProp"); hres = IHTMLLocation_QueryInterface(location, &IID_IDispatchEx, (void**)&dispex); @@ -3631,16 +3646,28 @@ static void test_doc_obj(IHTMLDocument2 *doc) hres = IHTMLWindow2_get_document(window, &doc_node2); ok(hres == S_OK, "get_document failed: %08lx\n", hres); ok(doc_node != doc_node2, "doc_node == doc_node2\n"); - IHTMLDocument2_Release(doc_node2);
hres = IHTMLDocument2_get_parentWindow(doc_node, &window2); todo_wine ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); todo_wine ok(window == window2, "window != window2\n"); - IHTMLDocument2_Release(doc_node); if(hres == S_OK) IHTMLWindow2_Release(window2);
+ hres = IHTMLDocument2_QueryInterface(doc_node2, &IID_IServiceProvider, (void**)&sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == S_OK, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) failed: %08lx\n", hres); + hres = IOleCommandTarget_QueryInterface(cmdtarget, &IID_IActiveScriptSite, (void**)&site2); + ok(hres == S_OK, "Command Target QI for IActiveScriptSite failed: %08lx\n", hres); + ok(site != site2, "site == site2\n"); + IOleCommandTarget_Release(cmdtarget); + IHTMLDocument2_Release(doc_node2); + IHTMLDocument2_Release(doc_node); + IServiceProvider_Release(sp); + IUnknown_Release(site2); + IUnknown_Release(site); + hres = IHTMLWindow2_get_location(window, &location2); ok(hres == S_OK, "get_location failed: %08lx\n", hres); ok(location == location2, "location != location2\n"); diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index f2ad881df39..f41d5749b3b 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -53,6 +53,7 @@ DEFINE_GUID(IID_IProxyManager,0x00000008,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00, DEFINE_OLEGUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0); DEFINE_GUID(SID_SContainerDispatch,0xb722be00,0x4e68,0x101b,0xa2,0xbc,0x00,0xaa,0x00,0x40,0x47,0x70); DEFINE_GUID(outer_test_iid,0xabcabc00,0,0,0,0,0,0,0,0,0,0x66); +extern const IID IID_IActiveScriptSite;
#define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE @@ -8730,8 +8731,11 @@ static void test_submit(void) static void test_QueryService(IHTMLDocument2 *doc, BOOL success) { IHTMLWindow2 *window, *sp_window; + IOleCommandTarget *cmdtarget; + IHTMLDocument2 *doc_node; IServiceProvider *sp; IHlinkFrame *hf; + IUnknown *unk; HRESULT hres;
hres = IHTMLDocument2_QueryInterface(doc, &IID_IServiceProvider, (void**)&sp); @@ -8748,6 +8752,9 @@ static void test_QueryService(IHTMLDocument2 *doc, BOOL success) ok(hf == &HlinkFrame, "hf != HlinkFrame\n"); IHlinkFrame_Release(hf);
+ hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == E_NOINTERFACE, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) returned: %08lx\n", hres); + IServiceProvider_Release(sp);
hres = IHTMLDocument2_get_parentWindow(doc, &window); @@ -8766,8 +8773,28 @@ static void test_QueryService(IHTMLDocument2 *doc, BOOL success) ok(hf == &HlinkFrame, "hf != HlinkFrame\n"); IHlinkFrame_Release(hf);
+ hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == E_NOINTERFACE, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) returned: %08lx\n", hres); + IServiceProvider_Release(sp); + + hres = IHTMLWindow2_get_document(window, &doc_node); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); IHTMLWindow2_Release(window); + + hres = IHTMLDocument2_QueryInterface(doc_node, &IID_IServiceProvider, (void**)&sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + IHTMLDocument2_Release(doc_node); + + hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == S_OK, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) failed: %08lx\n", hres); + ok(cmdtarget != NULL, "cmdtarget == NULL\n"); + hres = IOleCommandTarget_QueryInterface(cmdtarget, &IID_IActiveScriptSite, (void**)&unk); + ok(hres == S_OK, "Command Target QI for IActiveScriptSite failed: %08lx\n", hres); + IUnknown_Release(unk); + + IOleCommandTarget_Release(cmdtarget); + IServiceProvider_Release(sp); }
static void test_HTMLDocument_StreamLoad(void) @@ -9281,8 +9308,10 @@ static BOOL check_ie(void) static void test_ServiceProvider(void) { IHTMLDocument3 *doc3, *doc3_2; + IOleCommandTarget *cmdtarget; IServiceProvider *provider; IHTMLDocument2 *doc, *doc2; + IHTMLWindow2 *window; IUnknown *unk; HRESULT hres;
@@ -9318,6 +9347,29 @@ static void test_ServiceProvider(void) ok(hres == S_OK, "QueryService(HTMLEditServices) failed: %08lx\n", hres); IUnknown_Release(unk);
+ hres = IServiceProvider_QueryService(provider, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == E_NOINTERFACE, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) returned: %08lx\n", hres); + IServiceProvider_Release(provider); + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_document(window, &doc2); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); + IHTMLWindow2_Release(window); + + hres = IHTMLDocument2_QueryInterface(doc2, &IID_IServiceProvider, (void**)&provider); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + IHTMLDocument2_Release(doc2); + + hres = IServiceProvider_QueryService(provider, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == S_OK, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) failed: %08lx\n", hres); + ok(cmdtarget != NULL, "cmdtarget == NULL\n"); + hres = IOleCommandTarget_QueryInterface(cmdtarget, &IID_IActiveScriptSite, (void**)&unk); + ok(hres == S_OK, "Command Target QI for IActiveScriptSite failed: %08lx\n", hres); + IUnknown_Release(unk); + + IOleCommandTarget_Release(cmdtarget); IServiceProvider_Release(provider); release_document(doc); } diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 68ad3002a7f..1f3f4a1bb79 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -129,6 +129,7 @@ DEFINE_EXPECT(AddNamedItem); DEFINE_EXPECT(AddNamedItem2); DEFINE_EXPECT(ParseScriptText_script); DEFINE_EXPECT(ParseScriptText_script2); +DEFINE_EXPECT(ParseScriptText_script_with_prescript_site); DEFINE_EXPECT(ParseScriptText_execScript); DEFINE_EXPECT(GetScriptDispatch); DEFINE_EXPECT(funcDisp); @@ -186,6 +187,7 @@ static BOOL is_ie9plus, is_english; static IHTMLDocument2 *notif_doc; static IOleDocumentView *view; static IDispatchEx *window_dispex; +static IHTMLDocument2 *doc_obj; static BOOL doc_complete; static IDispatch *script_disp; static BOOL ax_objsafe; @@ -1924,7 +1926,8 @@ static IHTMLDocument2 *create_document(void) todo_wine #endif ok(hres == S_OK, "CoCreateInstance failed: %08lx\n", hres); - return SUCCEEDED(hres) ? doc : NULL; + doc_obj = SUCCEEDED(hres) ? doc : NULL; + return doc_obj; }
static void load_string(IHTMLDocument2 *doc, const char *str) @@ -3059,10 +3062,34 @@ static void test_ui(void)
static void test_sp(void) { - IServiceProvider *sp; + IServiceProvider *sp, *doc_sp, *doc_obj_sp, *window_sp; + IOleCommandTarget *cmdtarget; + IHTMLWindow2 *window; + IHTMLDocument2 *doc; IUnknown *unk; HRESULT hres;
+ hres = IDispatchEx_QueryInterface(window_dispex, &IID_IHTMLWindow2, (void**)&window); + ok(hres == S_OK, "QueryInterface(IHTMLWindow2) failed: %08lx\n", hres); + ok(window != NULL, "window is NULL\n"); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IServiceProvider, (void**)&window_sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + ok(window_sp != NULL, "window service provider is NULL\n"); + + hres = IHTMLWindow2_get_document(window, &doc); + ok(hres == S_OK, "QueryInterface(IHTMLDocument2) failed: %08lx\n", hres); + ok(doc != NULL, "doc is NULL\n"); + ok(doc != doc_obj, "doc node == doc obj\n"); + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IServiceProvider, (void**)&doc_sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + ok(doc_sp != NULL, "doc service provider is NULL\n"); + IHTMLDocument2_Release(doc); + hres = IHTMLDocument2_QueryInterface(doc_obj, &IID_IServiceProvider, (void**)&doc_obj_sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + ok(doc_obj_sp != NULL, "doc_obj service provider is NULL\n"); + hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp); ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres);
@@ -3070,7 +3097,60 @@ static void test_sp(void) ok(hres == S_OK, "Could not get SID_SContainerDispatch service: %08lx\n", hres); IUnknown_Release(unk);
+ hres = IServiceProvider_QueryService(sp, &SID_GetCaller, &IID_IServiceProvider, (void**)&unk); + ok(hres == E_NOINTERFACE, "QueryService(SID_GetCaller) returned: %08lx\n", hres); + hres = IServiceProvider_QueryService(doc_sp, &SID_GetCaller, &IID_IServiceProvider, (void**)&unk); + ok(hres == E_NOINTERFACE, "QueryService(SID_GetCaller) returned: %08lx\n", hres); + hres = IServiceProvider_QueryService(doc_obj_sp, &SID_GetCaller, &IID_IServiceProvider, (void**)&unk); + ok(hres == E_NOINTERFACE, "QueryService(SID_GetCaller) returned: %08lx\n", hres); + hres = IServiceProvider_QueryService(window_sp, &SID_GetCaller, &IID_IServiceProvider, (void**)&unk); + ok(hres == E_NOINTERFACE, "QueryService(SID_GetCaller) returned: %08lx\n", hres); + + hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == S_OK, "QueryService(IActiveScriptSite->IOleCommandTarget) failed: %08lx\n", hres); + ok(cmdtarget != NULL, "IOleCommandTarget is NULL\n"); + + hres = IActiveScriptSite_QueryInterface(site, &IID_IOleCommandTarget, (void**)&unk); + ok(hres == S_OK, "QueryInterface(IOleCommandTarget) failed: %08lx\n", hres); + ok(unk != NULL, "QueryInterface(IOleCommandTarget) is NULL\n"); + ok(cmdtarget == (IOleCommandTarget*)unk, "cmdtarget from QS not same as from QI\n"); + IUnknown_Release(unk); + hres = IServiceProvider_QueryService(doc_sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&unk); + ok(hres == S_OK, "QueryService(IActiveScriptSite->IOleCommandTarget) failed: %08lx\n", hres); + ok(cmdtarget == (IOleCommandTarget*)unk, "IActiveScriptSite service from document provider not same as site's\n"); + IUnknown_Release(unk); + hres = IServiceProvider_QueryService(doc_obj_sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&unk); + ok(hres == E_NOINTERFACE, "QueryService(IActiveScriptSite->IOleCommandTarget) returned: %08lx\n", hres); + hres = IServiceProvider_QueryService(window_sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&unk); + ok(hres == E_NOINTERFACE, "QueryService(IActiveScriptSite->IOleCommandTarget) returned: %08lx\n", hres); + + if(site2) { + IOleCommandTarget *cmdtarget2; + IServiceProvider *sp2; + + hres = IActiveScriptSite_QueryInterface(site2, &IID_IServiceProvider, (void**)&sp2); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + + hres = IServiceProvider_QueryService(sp2, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget2); + ok(hres == S_OK, "QueryService(IActiveScriptSite->IOleCommandTarget) failed: %08lx\n", hres); + ok(cmdtarget2 != NULL, "IOleCommandTarget is NULL\n"); + + hres = IActiveScriptSite_QueryInterface(site2, &IID_IOleCommandTarget, (void**)&unk); + ok(hres == S_OK, "QueryInterface(IOleCommandTarget) failed: %08lx\n", hres); + ok(unk != NULL, "QueryInterface(IOleCommandTarget) is NULL\n"); + ok(cmdtarget2 != (IOleCommandTarget*)unk, "cmdtarget from site2's QS same as from QI\n"); + ok(cmdtarget2 == cmdtarget, "site1's cmdtarget not same as site2's\n"); + IOleCommandTarget_Release(cmdtarget2); + IServiceProvider_Release(sp2); + IUnknown_Release(unk); + } + + IOleCommandTarget_Release(cmdtarget); + IServiceProvider_Release(window_sp); + IServiceProvider_Release(doc_obj_sp); + IServiceProvider_Release(doc_sp); IServiceProvider_Release(sp); + IHTMLWindow2_Release(window); }
static void test_script_run(void) @@ -3331,6 +3411,12 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
test_script_run(); return S_OK; + }else if(!lstrcmpW(pstrCode, L"with pre-script site")) { + CHECK_EXPECT(ParseScriptText_script_with_prescript_site); + ok(!lstrcmpW(pstrItemName, L"window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName)); + ok(!lstrcmpW(pstrDelimiter, L"</SCRIPT>"), "pstrDelimiter = %s\n", wine_dbgstr_w(pstrDelimiter)); + ok(dwFlags == (SCRIPTTEXT_ISVISIBLE|SCRIPTTEXT_HOSTMANAGESSOURCE), "dwFlags = %lx\n", dwFlags); + return S_OK; }
ok(0, "unexpected script %s\n", wine_dbgstr_w(pstrCode)); @@ -3406,6 +3492,8 @@ static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveSc CHECK_EXPECT(SetScriptSite);
ok(pass != NULL, "pass == NULL\n"); + if(site2) + ok(pass != site2, "pass == pre-script site\n");
hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteInterruptPoll, (void**)&poll); ok(hres == S_OK, "Could not get IActiveScriptSiteInterruptPoll interface: %08lx\n", hres); @@ -3695,6 +3783,7 @@ static HRESULT WINAPI ActiveScriptParse2_ParseScriptText(IActiveScriptParse *ifa ok(!lstrcmpW(pstrItemName, L"window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName)); ok(!lstrcmpW(pstrDelimiter, L"</SCRIPT>"), "pstrDelimiter = %s\n", wine_dbgstr_w(pstrDelimiter)); ok(dwFlags == (SCRIPTTEXT_ISVISIBLE | SCRIPTTEXT_HOSTMANAGESSOURCE), "dwFlags = %08lx\n", dwFlags); + test_sp(); return S_OK; }
@@ -4447,6 +4536,12 @@ static const char simple_script_str[] = "<script language="TestScript1">simple script</script>" "</body></html>";
+static const char simple_script_with_prescript_site_str[] = + "<html><head><meta http-equiv="x-ua-compatible" content="IE=9" /></head><body>" + "<script language="TestScript1">with pre-script site</script>" + "<script>if(true) try { Object.getPrototypeOf(Object); document.fail_prop = 1; } catch(e) {}</script>" + "</body></html>"; + static void test_insert_script_elem(IHTMLDocument2 *doc, const WCHAR *code, const WCHAR *lang) { IHTMLDOMNode *node, *body_node, *inserted_node; @@ -4524,10 +4619,16 @@ static void test_exec_script(IHTMLDocument2 *doc, const WCHAR *codew, const WCHA
static void test_simple_script(void) { + IOleCommandTarget *cmdtarget; IHTMLDocument2 *doc_node; + IServiceProvider *sp; IHTMLWindow2 *window; + IHTMLDocument6 *doc6; IHTMLDocument2 *doc; + DISPID dispid; HRESULT hres; + VARIANT v; + BSTR bstr;
doc = create_document(); if(!doc) @@ -4591,13 +4692,6 @@ static void test_simple_script(void)
test_exec_script(doc, L"execScript call", L"TestScript1");
- if(site) - IActiveScriptSite_Release(site); - if(site2) - IActiveScriptSite_Release(site2); - if(window_dispex) - IDispatchEx_Release(window_dispex); - hres = IHTMLDocument2_get_parentWindow(doc, &window); ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres);
@@ -4614,6 +4708,16 @@ static void test_simple_script(void) CHECK_CALLED(Close); CHECK_CALLED(Close2);
+ if(site) + IActiveScriptSite_Release(site); + if(site2) + IActiveScriptSite_Release(site2); + if(window_dispex) + IDispatchEx_Release(window_dispex); + site = NULL; + site2 = NULL; + window_dispex = NULL; + hres = IHTMLWindow2_get_document(window, &doc); ok(hres == S_OK, "get_document failed: %08lx\n", hres); ok(doc != doc_node, "doc == doc_node\n"); @@ -4621,6 +4725,112 @@ static void test_simple_script(void) IHTMLDocument2_Release(doc_node); IHTMLDocument2_Release(doc); IHTMLWindow2_Release(window); + + /* Obtaining the IActiveScriptSite before any script engines creates a site with JScript engine, + and is preserved after document gets loaded, and even keeps it from changing its compat mode. */ + doc = create_document(); + if(!doc) + return; + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_document(window, &doc_node); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); + IHTMLWindow2_Release(window); + + hres = IHTMLDocument2_QueryInterface(doc_node, &IID_IServiceProvider, (void**)&sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + IHTMLDocument2_Release(doc_node); + + hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == S_OK, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) failed: %08lx\n", hres); + ok(cmdtarget != NULL, "cmdtarget == NULL\n"); + + hres = IOleCommandTarget_QueryInterface(cmdtarget, &IID_IActiveScriptSite, (void**)&site2); + ok(hres == S_OK, "Command Target QI for IActiveScriptSite failed: %08lx\n", hres); + ok(site2 != NULL, "IActiveScriptSite is NULL\n"); + IOleCommandTarget_Release(cmdtarget); + IServiceProvider_Release(sp); + + SET_EXPECT(CreateInstance); + SET_EXPECT(GetInterfaceSafetyOptions); + SET_EXPECT(SetInterfaceSafetyOptions); + SET_EXPECT(SetProperty_INVOKEVERSIONING); + SET_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK); + SET_EXPECT(InitNew); + SET_EXPECT(SetScriptSite); + SET_EXPECT(GetScriptState); + SET_EXPECT(SetScriptState_STARTED); + SET_EXPECT(AddNamedItem); + SET_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION_FALSE); + SET_EXPECT(ParseScriptText_script_with_prescript_site); + SET_EXPECT(SetScriptState_CONNECTED); + + load_doc(doc, simple_script_with_prescript_site_str); + + CHECK_CALLED(CreateInstance); + CHECK_CALLED(GetInterfaceSafetyOptions); + CHECK_CALLED(SetInterfaceSafetyOptions); + CHECK_CALLED(SetProperty_INVOKEVERSIONING); + CHECK_CALLED(SetProperty_HACK_TRIDENTEVENTSINK); + CHECK_CALLED(InitNew); + CHECK_CALLED(SetScriptSite); + CHECK_CALLED(GetScriptState); + CHECK_CALLED(SetScriptState_STARTED); + CHECK_CALLED(AddNamedItem); + CHECK_CALLED(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION_FALSE); + CHECK_CALLED(ParseScriptText_script_with_prescript_site); + CHECK_CALLED(SetScriptState_CONNECTED); + + if(site) + IActiveScriptSite_Release(site); + + bstr = SysAllocString(L"fail_prop"); + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &dispid); + ok(hres == DISP_E_UNKNOWNNAME, "GetIDsOfNames(fail_prop) returned: %08lx\n", hres); + SysFreeString(bstr); + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_document(window, &doc_node); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); + IHTMLWindow2_Release(window); + + hres = IHTMLDocument2_QueryInterface(doc_node, &IID_IHTMLDocument6, (void**)&doc6); + ok(hres == S_OK, "Could not get IHTMLDocument6 iface: %08lx\n", hres); + hres = IHTMLDocument6_get_documentMode(doc6, &v); + ok(V_VT(&v) == VT_R4, "V_VT(documentMode) = %d\n", V_VT(&v)); + ok(V_R4(&v) == 5.0, "V_R4(documentMode) = %f\n", V_R4(&v)); + IHTMLDocument6_Release(doc6); + + hres = IHTMLDocument2_QueryInterface(doc_node, &IID_IServiceProvider, (void**)&sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + IHTMLDocument2_Release(doc_node); + + hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == S_OK, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) failed: %08lx\n", hres); + ok(cmdtarget != NULL, "cmdtarget == NULL\n"); + + hres = IOleCommandTarget_QueryInterface(cmdtarget, &IID_IActiveScriptSite, (void**)&site); + ok(hres == S_OK, "Command Target QI for IActiveScriptSite failed: %08lx\n", hres); + ok(site == site2, "site != site2\n"); + IOleCommandTarget_Release(cmdtarget); + IServiceProvider_Release(sp); + + SET_EXPECT(SetScriptState_DISCONNECTED); + SET_EXPECT(Close); + + IHTMLDocument2_Release(doc); + + CHECK_CALLED(SetScriptState_DISCONNECTED); + CHECK_CALLED(Close); + + IActiveScriptSite_Release(site2); + IActiveScriptSite_Release(site); + if(window_dispex) + IDispatchEx_Release(window_dispex); }
static void run_from_moniker(IMoniker *mon)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/script.c | 29 +++++++++++++++++++++++++++-- dlls/mshtml/tests/script.c | 16 +++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 1af5167efaa..43fa6e42c66 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -759,9 +759,34 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID { ScriptHost *This = impl_from_IOleCommandTarget(iface);
- FIXME("(%p)->(%s %ld %ld %s %p)\n", This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, wine_dbgstr_variant(pvaIn), pvaOut); + TRACE("(%p)->(%s %ld %ld %s %p)\n", This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, wine_dbgstr_variant(pvaIn), pvaOut);
- return E_NOTIMPL; + if(!pguidCmdGroup) { + FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup)); + return OLECMDERR_E_UNKNOWNGROUP; + } + + if(IsEqualGUID(&CGID_ScriptSite, pguidCmdGroup)) { + switch(nCmdID) { + case CMDID_SCRIPTSITE_SECURITY_WINDOW: + if(!This->window || !This->window->base.outer_window) { + FIXME("No window\n"); + return E_FAIL; + } + V_VT(pvaOut) = VT_DISPATCH; + V_DISPATCH(pvaOut) = (IDispatch*)&This->window->base.outer_window->base.IHTMLWindow2_iface; + IDispatch_AddRef(V_DISPATCH(pvaOut)); + break; + + default: + FIXME("Unsupported nCmdID %ld of CGID_ScriptSite group\n", nCmdID); + return OLECMDERR_E_NOTSUPPORTED; + } + return S_OK; + } + + FIXME("Unsupported pguidCmdGroup %s\n", debugstr_guid(pguidCmdGroup)); + return OLECMDERR_E_UNKNOWNGROUP; }
static const IOleCommandTargetVtbl OleCommandTargetVtbl = { diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 1f3f4a1bb79..7d6d024553d 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -3063,11 +3063,12 @@ static void test_ui(void) static void test_sp(void) { IServiceProvider *sp, *doc_sp, *doc_obj_sp, *window_sp; + IHTMLWindow2 *window, *cmdtarget_window; IOleCommandTarget *cmdtarget; - IHTMLWindow2 *window; IHTMLDocument2 *doc; IUnknown *unk; HRESULT hres; + VARIANT var;
hres = IDispatchEx_QueryInterface(window_dispex, &IID_IHTMLWindow2, (void**)&window); ok(hres == S_OK, "QueryInterface(IHTMLWindow2) failed: %08lx\n", hres); @@ -3145,6 +3146,19 @@ static void test_sp(void) IUnknown_Release(unk); }
+ V_VT(&var) = VT_EMPTY; + hres = IOleCommandTarget_Exec(cmdtarget, &CGID_ScriptSite, CMDID_SCRIPTSITE_SECURITY_WINDOW, 0, NULL, &var); + ok(hres == S_OK, "Exec failed: %08lx\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(CMDID_SCRIPTSITE_SECURITY_WINDOW) = %d\n", V_VT(&var)); + ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(CMDID_SCRIPTSITE_SECURITY_WINDOW) = NULL\n"); + + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLWindow2, (void**)&cmdtarget_window); + ok(hres == S_OK, "QueryInterface(IHTMLWindow2) failed: %08lx\n", hres); + ok(cmdtarget_window != NULL, "cmdtarget_window is NULL\n"); + ok(window == cmdtarget_window, "window != cmdtarget_window\n"); + IHTMLWindow2_Release(cmdtarget_window); + VariantClear(&var); + IOleCommandTarget_Release(cmdtarget); IServiceProvider_Release(window_sp); IServiceProvider_Release(doc_obj_sp);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/vbscript/tests/caller.c | 14 +++++++++++++- dlls/vbscript/vbscript.c | 9 +++++++++ dlls/vbscript/vbscript.h | 1 + 3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/vbscript/tests/caller.c b/dlls/vbscript/tests/caller.c index 19eccfe715d..8b99fa7e129 100644 --- a/dlls/vbscript/tests/caller.c +++ b/dlls/vbscript/tests/caller.c @@ -74,6 +74,7 @@ extern const CLSID CLSID_VBScript; expect_ ## func = called_ ## func = FALSE
DEFINE_EXPECT(sp_caller_QI_NULL); +DEFINE_EXPECT(site_QI_NULL); DEFINE_EXPECT(testGetCaller); DEFINE_EXPECT(testGetCallerVBS); DEFINE_EXPECT(testGetCallerNested); @@ -303,7 +304,9 @@ static HRESULT WINAPI Test_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WO break; }
- case DISPID_TEST_TESTGETCALLERVBS: + case DISPID_TEST_TESTGETCALLERVBS: { + IUnknown *unk; + CHECK_EXPECT(testGetCallerVBS);
ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags); @@ -318,7 +321,14 @@ static HRESULT WINAPI Test_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WO hres = IServiceProvider_QueryService(pspCaller, &SID_GetCaller, &IID_IServiceProvider, (void**)&caller); ok(hres == E_NOINTERFACE, "QueryService(SID_GetCaller) returned: %08lx\n", hres); ok(caller == NULL, "caller != NULL\n"); + + SET_EXPECT(site_QI_NULL); + hres = IServiceProvider_QueryService(pspCaller, &IID_IActiveScriptSite, &IID_NULL, (void**)&unk); + ok(hres == E_NOINTERFACE, "QueryService(IActiveScriptSite->NULL) returned: %08lx\n", hres); + ok(!unk, "unk != NULL\n"); + CHECK_CALLED(site_QI_NULL); break; + }
case DISPID_TEST_TESTGETCALLERNESTED: CHECK_EXPECT(testGetCallerNested); @@ -374,6 +384,8 @@ static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) { *ppv = iface; }else { + if(IsEqualGUID(&IID_NULL, riid)) + CHECK_EXPECT(site_QI_NULL); *ppv = NULL; return E_NOINTERFACE; } diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 39a5e3b1648..84a8e0bb97f 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -421,6 +421,14 @@ static HRESULT WINAPI vbcaller_QueryService(IServiceProvider *iface, REFGUID gui { struct vbcaller *This = vbcaller_from_IServiceProvider(iface);
+ if(IsEqualGUID(guidService, &IID_IActiveScriptSite)) { + TRACE("(%p)->(IID_IActiveScriptSite)\n", This); + if(This->ctx->site) + return IActiveScriptSite_QueryInterface(This->ctx->site, riid, ppv); + *ppv = NULL; + return E_NOINTERFACE; + } + if(IsEqualGUID(guidService, &SID_GetCaller)) { TRACE("(%p)->(SID_GetCaller)\n", This); *ppv = NULL; @@ -1224,6 +1232,7 @@ HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pU return E_OUTOFMEMORY; }
+ vbcaller->ctx = ctx; ctx->vbcaller = vbcaller; ctx->safeopt = INTERFACE_USES_DISPEX; list_init(&ctx->objects); diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 56e68411f45..6b67c8b1bc5 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -187,6 +187,7 @@ struct vbcaller {
LONG ref;
+ script_ctx_t *ctx; IServiceProvider *caller; };
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/jsutils.c | 8 ++++++++ dlls/jscript/tests/caller.c | 10 ++++++++++ dlls/mshtml/tests/script.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+)
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index 80e068fc529..12f41acd398 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -1035,6 +1035,14 @@ static HRESULT WINAPI JSCaller_QueryService(IServiceProvider *iface, REFGUID gui { JSCaller *This = impl_from_IServiceProvider(iface);
+ if(IsEqualGUID(guidService, &IID_IActiveScriptSite)) { + TRACE("(%p)->(IID_IActiveScriptSite)\n", This); + if(This->ctx && This->ctx->site) + return IActiveScriptSite_QueryInterface(This->ctx->site, riid, ppv); + *ppv = NULL; + return E_NOINTERFACE; + } + if(IsEqualGUID(guidService, &SID_GetCaller)) { TRACE("(%p)->(SID_GetCaller)\n", This); *ppv = NULL; diff --git a/dlls/jscript/tests/caller.c b/dlls/jscript/tests/caller.c index 99b6a21e7fb..7bb7d4a8fe1 100644 --- a/dlls/jscript/tests/caller.c +++ b/dlls/jscript/tests/caller.c @@ -75,6 +75,7 @@ static const CLSID CLSID_JScript = expect_ ## func = called_ ## func = FALSE
DEFINE_EXPECT(sp_caller_QI_NULL); +DEFINE_EXPECT(site_QI_NULL); DEFINE_EXPECT(testArgConv); DEFINE_EXPECT(testGetCaller); DEFINE_EXPECT(testGetCallerJS); @@ -254,6 +255,7 @@ static void test_change_types(IVariantChangeType *change_type, IDispatch *obj_di static void test_caller(IServiceProvider *caller, IDispatch *arg_obj) { IVariantChangeType *change_type; + IUnknown *unk; HRESULT hres;
hres = IServiceProvider_QueryService(caller, &SID_VariantConversion, &IID_IVariantChangeType, (void**)&change_type); @@ -263,6 +265,12 @@ static void test_caller(IServiceProvider *caller, IDispatch *arg_obj) test_change_types(change_type, arg_obj);
IVariantChangeType_Release(change_type); + + SET_EXPECT(site_QI_NULL); + hres = IServiceProvider_QueryService(caller, &IID_IActiveScriptSite, &IID_NULL, (void**)&unk); + ok(hres == E_NOINTERFACE, "Querying for IActiveScriptSite->NULL returned: %08lx\n", hres); + ok(!unk, "unk != NULL\n"); + CHECK_CALLED(site_QI_NULL); }
static IServiceProvider sp_caller_obj; @@ -567,6 +575,8 @@ static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) { *ppv = iface; }else { + if(IsEqualGUID(&IID_NULL, riid)) + CHECK_EXPECT(site_QI_NULL); *ppv = NULL; return E_NOINTERFACE; } diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 7d6d024553d..df0bc4e200d 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -314,6 +314,36 @@ fail: return SysAllocString(L"File"); }
+static void test_sp_caller(IServiceProvider *sp) +{ + IOleCommandTarget *cmdtarget; + IServiceProvider *caller; + IHTMLWindow2 *window; + HRESULT hres; + VARIANT var; + + hres = IServiceProvider_QueryService(sp, &SID_GetCaller, &IID_IServiceProvider, (void**)&caller); + ok(hres == S_OK, "QueryService(SID_GetCaller) returned: %08lx\n", hres); + ok(!caller, "caller != NULL\n"); + + hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); + ok(hres == S_OK, "QueryService(IActiveScriptSite->IOleCommandTarget) failed: %08lx\n", hres); + ok(cmdtarget != NULL, "IOleCommandTarget is NULL\n"); + + V_VT(&var) = VT_EMPTY; + hres = IOleCommandTarget_Exec(cmdtarget, &CGID_ScriptSite, CMDID_SCRIPTSITE_SECURITY_WINDOW, 0, NULL, &var); + ok(hres == S_OK, "Exec failed: %08lx\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(CMDID_SCRIPTSITE_SECURITY_WINDOW) = %d\n", V_VT(&var)); + ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(CMDID_SCRIPTSITE_SECURITY_WINDOW) = NULL\n"); + IOleCommandTarget_Release(cmdtarget); + + hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLWindow2, (void**)&window); + ok(hres == S_OK, "QueryInterface(IHTMLWindow2) failed: %08lx\n", hres); + ok(window != NULL, "window is NULL\n"); + IHTMLWindow2_Release(window); + VariantClear(&var); +} + static void test_script_vars(unsigned argc, VARIANTARG *argv) { static const WCHAR *const jsobj_names[] = { L"abc", L"foO", L"bar", L"TostRing", L"hasownpropERty" }; @@ -1171,6 +1201,7 @@ static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID ok(!pvarRes, "pvarRes != NULL\n"); ok(pei != NULL, "pei == NULL\n");
+ test_sp_caller(pspCaller); return S_OK;
case DISPID_EXTERNAL_TODO_WINE_OK:
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=142367
Your paranoid android.
=== debian11b (64 bit WoW report) ===
quartz: dsoundrender: Timeout
Jacek Caban (@jacek) commented about dlls/mshtml/script.c:
+void move_script_hosts(HTMLInnerWindow *window, HTMLInnerWindow *new_window) +{
- ScriptHost *iter, *iter2;
- if(list_empty(&window->script_hosts))
return;
- LIST_FOR_EACH_ENTRY_SAFE(iter, iter2, &window->script_hosts, ScriptHost, entry) {
iter->window = new_window;
list_remove(&iter->entry);
list_add_tail(&new_window->script_hosts, &iter->entry);
- }
- lock_document_mode(new_window->doc);
+}
Why do we need it? It's weird seems to be yet another side effect that MSHTML internally differently represents document node object, you'd see that if you used `iface_cmp` in your tests checking that the node changed. Can we just drop the first patch and associated tests?
On Thu Jan 25 21:18:03 2024 +0000, Jacek Caban wrote:
Why do we need it? It's weird and it seems to be yet another side effect of the fact that MSHTML internally differently represents document node object, you'd see that if you used `iface_cmp` in your tests checking that the node changed. Can we just drop the first patch and associated tests?
Sorry, I've been having some difficulty understanding what you meant + testing it. For me, Windows crashes if I use the old doc_node from before document is loaded (even if I don't release it) but it *is different* in terms of raw pointer value, so doesn't that mean it gets "moved" as well?
On Fri Jan 26 16:05:26 2024 +0000, Gabriel Ivăncescu wrote:
Sorry, I've been having some difficulty understanding what you meant + testing it. For me, Windows crashes if I use the old doc_node from before document is loaded (even if I don't release it) but it *is different* in terms of raw pointer value, so doesn't that mean it gets "moved" as well? EDIT: Here's an example diff:
diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index 1f3f4a1..ddeebee 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -4619,8 +4619,8 @@ static void test_exec_script(IHTMLDocument2 *doc, const WCHAR *codew, const WCHA static void test_simple_script(void) { + IHTMLDocument2 *doc_node, *doc_node2; IOleCommandTarget *cmdtarget; - IHTMLDocument2 *doc_node; IServiceProvider *sp; IHTMLWindow2 *window; IHTMLDocument6 *doc6; @@ -4735,13 +4735,12 @@ static void test_simple_script(void) hres = IHTMLDocument2_get_parentWindow(doc, &window); ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); - hres = IHTMLWindow2_get_document(window, &doc_node); + hres = IHTMLWindow2_get_document(window, &doc_node2); ok(hres == S_OK, "get_document failed: %08lx\n", hres); IHTMLWindow2_Release(window); - hres = IHTMLDocument2_QueryInterface(doc_node, &IID_IServiceProvider, (void**)&sp); + hres = IHTMLDocument2_QueryInterface(doc_node2, &IID_IServiceProvider, (void**)&sp); ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); - IHTMLDocument2_Release(doc_node); hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget); ok(hres == S_OK, "QueryService(IID_IActiveScriptSite->IID_IOleCommandTarget) failed: %08lx\n", hres); @@ -4807,6 +4806,9 @@ static void test_simple_script(void) hres = IHTMLDocument2_QueryInterface(doc_node, &IID_IServiceProvider, (void**)&sp); ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + trace("doc_node %p, doc_node2 %p\n", doc_node, doc_node2); + ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)doc_node2), "doc_node != doc_node2\n"); + IHTMLDocument2_Release(doc_node2); IHTMLDocument2_Release(doc_node); hres = IServiceProvider_QueryService(sp, &IID_IActiveScriptSite, &IID_IOleCommandTarget, (void**)&cmdtarget);
`iface_cmp` crashes though.
My main question was why do we care?
On Fri Jan 26 17:26:38 2024 +0000, Jacek Caban wrote:
My main question was why do we care?
It's not a strong reason, I just wanted to have the tests pass when I wrote them since the implementation wasn't too complicated, although quirky. I can remove it though.