From 75b56cce431e9889383407b15110a7737d490a16 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 20 Oct 2009 19:28:26 +0000 Subject: [PATCH] -sync mshtml_winetest with wine 1.1.31 svn path=/trunk/; revision=43657 --- rostests/winetests/mshtml/dom.c | 956 +++++++++++--- rostests/winetests/mshtml/events.c | 1554 +++++++++++++++++++++++ rostests/winetests/mshtml/htmldoc.c | 388 ++++-- rostests/winetests/mshtml/mshtml.rbuild | 1 + rostests/winetests/mshtml/mshtml_test.h | 38 + rostests/winetests/mshtml/protocol.c | 130 +- rostests/winetests/mshtml/script.c | 453 ++++++- rostests/winetests/mshtml/testlist.c | 4 +- 8 files changed, 3156 insertions(+), 368 deletions(-) create mode 100644 rostests/winetests/mshtml/events.c create mode 100644 rostests/winetests/mshtml/mshtml_test.h diff --git a/rostests/winetests/mshtml/dom.c b/rostests/winetests/mshtml/dom.c index 249968d4250..c13c0a8c606 100644 --- a/rostests/winetests/mshtml/dom.c +++ b/rostests/winetests/mshtml/dom.c @@ -31,6 +31,7 @@ #include "mshtmhst.h" #include "docobj.h" #include "dispex.h" +#include "mshtml_test.h" static const char doc_blank[] = ""; static const char doc_str1[] = "test"; @@ -41,7 +42,7 @@ static const char range_test2_str[] = static const char elem_test_str[] = "test" "text test" - "link" + "link" "" "" "" @@ -58,14 +59,10 @@ static const char cond_comment_str[] = "" ""; -static const WCHAR noneW[] = {'N','o','n','e',0}; - static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0}; static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0}; static WCHAR wordW[] = {'w','o','r','d',0}; -static const WCHAR text_javascriptW[] = {'t','e','x','t','/','j','a','v','a','s','c','r','i','p','t',0}; - typedef enum { ET_NONE, ET_HTML, @@ -98,6 +95,32 @@ static const IID * const none_iids[] = { NULL }; +static const IID * const doc_node_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLDOMNode2, + &IID_IHTMLDocument, + &IID_IHTMLDocument2, + &IID_IHTMLDocument3, + &IID_IHTMLDocument4, + &IID_IHTMLDocument5, + &IID_IDispatchEx, + &IID_IConnectionPointContainer, + &IID_IInternetHostSecurityManager, + NULL +}; + +static const IID * const doc_obj_iids[] = { + &IID_IHTMLDocument, + &IID_IHTMLDocument2, + &IID_IHTMLDocument3, + &IID_IHTMLDocument4, + &IID_IHTMLDocument5, + &IID_IDispatchEx, + &IID_IConnectionPointContainer, + &IID_ICustomDoc, + NULL +}; + static const IID * const elem_iids[] = { &IID_IHTMLDOMNode, &IID_IHTMLDOMNode2, @@ -330,7 +353,7 @@ static const elem_type_info_t elem_type_infos[] = { {"HEAD", elem_iids, NULL}, {"TITLE", elem_iids, NULL}, {"BODY", body_iids, &DIID_DispHTMLBody}, - {"A", anchor_iids, NULL}, + {"A", anchor_iids, &DIID_DispHTMLAnchorElement}, {"INPUT", input_iids, &DIID_DispHTMLInputElement}, {"SELECT", select_iids, &DIID_DispHTMLSelectElement}, {"TEXTAREA", textarea_iids, NULL}, @@ -351,15 +374,6 @@ static const elem_type_info_t elem_type_infos[] = { {"IFRAME", iframe_iids, &DIID_DispHTMLIFrame} }; -static const char *dbgstr_w(LPCWSTR str) -{ - static char buf[512]; - if(!str) - return "(null)"; - WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL); - return buf; -} - static const char *dbgstr_guid(REFIID riid) { static char buf[50]; @@ -374,9 +388,9 @@ static const char *dbgstr_guid(REFIID riid) static int strcmp_wa(LPCWSTR strw, const char *stra) { - WCHAR buf[512]; - MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR)); - return lstrcmpW(strw, buf); + CHAR buf[512]; + WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); + return lstrcmpA(stra, buf); } static BSTR a2bstr(const char *str) @@ -400,7 +414,7 @@ static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2) IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1); IUnknown_Release(unk1); - IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk2); + IUnknown_QueryInterface(iface2, &IID_IUnknown, (void**)&unk2); IUnknown_Release(unk2); return unk1 == unk2; @@ -442,18 +456,19 @@ static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids) } } -#define test_disp(u,id) _test_disp(__LINE__,u,id) -static void _test_disp(unsigned line, IUnknown *unk, const IID *diid) +#define test_get_dispid(u,id) _test_disp(__LINE__,u,id) +static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid) { IDispatchEx *dispex; ITypeInfo *typeinfo; + BOOL ret = FALSE; UINT ticnt; HRESULT hres; hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex); ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres); if(FAILED(hres)) - return; + return FALSE; ticnt = 0xdeadbeef; hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt); @@ -468,13 +483,65 @@ static void _test_disp(unsigned line, IUnknown *unk, const IID *diid) hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr); ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres); - ok_(__FILE__,line) (IsEqualGUID(&type_attr->guid, diid), "unexpected guid %s\n", dbgstr_guid(&type_attr->guid)); + if(hres == S_OK) { + *iid = type_attr->guid; + ret = TRUE; + } ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr); ITypeInfo_Release(typeinfo); } IDispatchEx_Release(dispex); + return ret; +} + +#define test_disp_value(u) _test_disp_value(__LINE__,u,v) +static void _test_disp_value(unsigned line, IUnknown *unk, const char *val) +{ + DISPPARAMS dp = {NULL,NULL,0,0}; + IDispatchEx *dispex; + EXCEPINFO ei; + VARIANT var; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex); + ok_(__FILE__,line)(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres); + if(FAILED(hres)) + return; + + hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL); + IDispatchEx_Release(dispex); + ok_(__FILE__,line)(hres == S_OK, "InvokeEx(DISPID_VALUE) returned: %08x\n", hres); + + ok_(__FILE__,line)(V_VT(&var) == VT_BSTR, "V_VT(value) = %d\n", V_VT(&var)); + ok_(__FILE__,line)(!strcmp_wa(V_BSTR(&var), val), "value = %s, expected %s\n", wine_dbgstr_w(V_BSTR(&var)), val); + VariantClear(&var); +} + +#define test_disp(u,id,v) _test_disp(__LINE__,u,id,v) +static void _test_disp(unsigned line, IUnknown *unk, const IID *diid, const char *val) +{ + IID iid; + + if(_test_get_dispid(line, unk, &iid)) + ok_(__FILE__,line) (IsEqualGUID(&iid, diid), "unexpected guid %s\n", dbgstr_guid(&iid)); + + if(val) + _test_disp_value(line, unk, val); +} + +#define test_disp2(u,id,id2,v) _test_disp2(__LINE__,u,id,id2,v) +static void _test_disp2(unsigned line, IUnknown *unk, const IID *diid, const IID *diid2, const char *val) +{ + IID iid; + + if(_test_get_dispid(line, unk, &iid)) + ok_(__FILE__,line) (IsEqualGUID(&iid, diid) || broken(IsEqualGUID(&iid, diid2)), + "unexpected guid %s\n", dbgstr_guid(&iid)); + + if(val) + _test_disp_value(line, unk, val); } #define get_elem_iface(u) _get_elem_iface(__LINE__,u) @@ -521,6 +588,17 @@ static IHTMLDOMNode *_get_node_iface(unsigned line, IUnknown *unk) return node; } +#define get_node2_iface(u) _get_node2_iface(__LINE__,u) +static IHTMLDOMNode2 *_get_node2_iface(unsigned line, IUnknown *unk) +{ + IHTMLDOMNode2 *node; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&node); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMNode2: %08x\n", hres); + return node; +} + #define get_img_iface(u) _get_img_iface(__LINE__,u) static IHTMLImgElement *_get_img_iface(unsigned line, IUnknown *unk) { @@ -532,6 +610,17 @@ static IHTMLImgElement *_get_img_iface(unsigned line, IUnknown *unk) return img; } +#define get_anchor_iface(u) _get_anchor_iface(__LINE__,u) +static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk) +{ + IHTMLAnchorElement *anchor; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLAnchorElement, (void**)&anchor); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLAnchorElement: %08x\n", hres); + return anchor; +} + #define test_node_name(u,n) _test_node_name(__LINE__,u,n) static void _test_node_name(unsigned line, IUnknown *unk, const char *exname) { @@ -542,11 +631,47 @@ static void _test_node_name(unsigned line, IUnknown *unk, const char *exname) hres = IHTMLDOMNode_get_nodeName(node, &name); IHTMLDOMNode_Release(node); ok_(__FILE__, line) (hres == S_OK, "get_nodeName failed: %08x\n", hres); - ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", dbgstr_w(name), exname); + ok_(__FILE__, line) (!strcmp_wa(name, exname), "got name: %s, expected %s\n", wine_dbgstr_w(name), exname); SysFreeString(name); } +#define get_owner_doc(u) _get_owner_doc(__LINE__,u) +static IHTMLDocument2 *_get_owner_doc(unsigned line, IUnknown *unk) +{ + IHTMLDOMNode2 *node = _get_node2_iface(line, unk); + IDispatch *disp = (void*)0xdeadbeef; + IHTMLDocument2 *doc; + HRESULT hres; + + hres = IHTMLDOMNode2_get_ownerDocument(node, &disp); + IHTMLDOMNode2_Release(node); + ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres); + ok_(__FILE__,line)(disp != NULL, "disp = NULL\n"); + + hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc); + IDispatch_Release(disp); + ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres); + + return doc; +} + +#define clone_node(n,d) _clone_node(__LINE__,n,d) +static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep) +{ + IHTMLDOMNode *node = _get_node_iface(line, unk); + IHTMLDOMNode *ret = NULL; + HRESULT hres; + + hres = IHTMLDOMNode_cloneNode(node, deep, &ret); + IHTMLDOMNode_Release(node); + ok_(__FILE__,line)(hres == S_OK, "cloneNode failed: %08x\n", hres); + ok_(__FILE__,line)(ret != NULL, "ret == NULL\n"); + + return ret; + +} + #define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n) static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag) { @@ -557,7 +682,7 @@ static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag) hres = IHTMLElement_get_tagName(elem, &tag); IHTMLElement_Release(elem); ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres); - ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", dbgstr_w(tag), extag); + ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag); SysFreeString(tag); } @@ -568,8 +693,8 @@ static void _test_elem_type(unsigned line, IUnknown *unk, elem_type_t type) _test_elem_tag(line, unk, elem_type_infos[type].tag); _test_ifaces(line, unk, elem_type_infos[type].iids); - if(elem_type_infos[type].dispiid) - _test_disp(line, unk, elem_type_infos[type].dispiid); + if(elem_type_infos[type].dispiid && type != ET_A) + _test_disp(line, unk, elem_type_infos[type].dispiid, "[object]"); } #define get_node_type(n) _get_node_type(__LINE__,n) @@ -640,7 +765,7 @@ static void _test_elem_attr(unsigned line, IHTMLElement *elem, const char *name, if(exval) { ok_(__FILE__,line) (V_VT(&value) == VT_BSTR, "vt=%d\n", V_VT(&value)); - ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&value), exval), "unexpected value %s\n", dbgstr_w(V_BSTR(&value))); + ok_(__FILE__,line) (!strcmp_wa(V_BSTR(&value), exval), "unexpected value %s\n", wine_dbgstr_w(V_BSTR(&value))); }else { ok_(__FILE__,line) (V_VT(&value) == VT_NULL, "vt=%d\n", V_VT(&value)); } @@ -667,12 +792,32 @@ static void _test_elem_offset(unsigned line, IUnknown *unk) IHTMLElement_Release(elem); } -static void test_doc_elem(IHTMLDocument2 *doc) +#define get_doc_node(d) _get_doc_node(__LINE__,d) +static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc) +{ + IHTMLWindow2 *window; + IHTMLDocument2 *ret; + HRESULT hres; + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres); + + hres = IHTMLWindow2_get_document(window, &ret); + ok_(__FILE__,line)(hres == S_OK, "get_document failed: %08x\n", hres); + ok_(__FILE__,line)(ret != NULL, "document = NULL\n"); + + return ret; +} + +static void test_get_set_attr(IHTMLDocument2 *doc) { IHTMLElement *elem; IHTMLDocument3 *doc3; HRESULT hres; + BSTR bstr; + VARIANT val; + /* grab an element to test with */ hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3); ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres); @@ -680,8 +825,60 @@ static void test_doc_elem(IHTMLDocument2 *doc) IHTMLDocument3_Release(doc3); ok(hres == S_OK, "get_documentElement failed: %08x\n", hres); - test_node_name((IUnknown*)elem, "HTML"); - test_elem_tag((IUnknown*)elem, "HTML"); + /* get a non-present attribute */ + bstr = a2bstr("notAnAttribute"); + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_NULL, "variant type should have been VT_NULL (0x%x), was: 0x%x\n", VT_NULL, V_VT(&val)); + VariantClear(&val); + SysFreeString(bstr); + + /* get a present attribute */ + bstr = a2bstr("scrollHeight"); + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_I4, "variant type should have been VT_I4 (0x%x), was: 0x%x\n", VT_I4, V_VT(&val)); + VariantClear(&val); + SysFreeString(bstr); + + /* create a new BSTR attribute */ + bstr = a2bstr("newAttribute"); + + V_VT(&val) = VT_BSTR; + V_BSTR(&val) = a2bstr("the value"); + hres = IHTMLElement_setAttribute(elem, bstr, val, 0); + ok(hres == S_OK, "setAttribute failed: %08x\n", hres); + VariantClear(&val); + + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_BSTR, "variant type should have been VT_BSTR (0x%x), was: 0x%x\n", VT_BSTR, V_VT(&val)); + ok(strcmp_wa(V_BSTR(&val), "the value") == 0, "variant value should have been L\"the value\", was %s\n", wine_dbgstr_w(V_BSTR(&val))); + VariantClear(&val); + + /* overwrite the attribute with a BOOL */ + V_VT(&val) = VT_BOOL; + V_BOOL(&val) = VARIANT_TRUE; + hres = IHTMLElement_setAttribute(elem, bstr, val, 0); + ok(hres == S_OK, "setAttribute failed: %08x\n", hres); + VariantClear(&val); + + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val)); + ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val)); + VariantClear(&val); + + SysFreeString(bstr); + + /* case-insensitive */ + bstr = a2bstr("newattribute"); + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + todo_wine ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val)); + todo_wine ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val)); + VariantClear(&val); + SysFreeString(bstr); IHTMLElement_Release(elem); } @@ -702,6 +899,21 @@ static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc) return elem; } +#define test_anchor_href(a,h) _test_anchor_href(__LINE__,a,h) +static void _test_anchor_href(unsigned line, IUnknown *unk, const char *exhref) +{ + IHTMLAnchorElement *anchor = _get_anchor_iface(line, unk); + BSTR str; + HRESULT hres; + + hres = IHTMLAnchorElement_get_href(anchor, &str); + ok_(__FILE__,line)(hres == S_OK, "get_href failed: %08x\n", hres); + ok_(__FILE__,line)(!strcmp_wa(str, exhref), "href = %s, expected %s\n", wine_dbgstr_w(str), exhref); + SysFreeString(str); + + _test_disp_value(line, unk, exhref); +} + #define test_option_text(o,t) _test_option_text(__LINE__,o,t) static void _test_option_text(unsigned line, IHTMLOptionElement *option, const char *text) { @@ -710,7 +922,7 @@ static void _test_option_text(unsigned line, IHTMLOptionElement *option, const c hres = IHTMLOptionElement_get_text(option, &bstr); ok_(__FILE__,line) (hres == S_OK, "get_text failed: %08x\n", hres); - ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", dbgstr_w(bstr)); + ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr); } @@ -736,7 +948,7 @@ static void _test_option_value(unsigned line, IHTMLOptionElement *option, const hres = IHTMLOptionElement_get_value(option, &bstr); ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres); - ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", dbgstr_w(bstr)); + ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr); } @@ -831,9 +1043,9 @@ static void _test_select_value(unsigned line, IHTMLSelectElement *select, const hres = IHTMLSelectElement_get_value(select, &val); ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres); if(exval) - ok_(__FILE__,line) (!strcmp_wa(val, exval), "unexpected value %s\n", dbgstr_w(val)); + ok_(__FILE__,line) (!strcmp_wa(val, exval), "unexpected value %s\n", wine_dbgstr_w(val)); else - ok_(__FILE__,line) (val == NULL, "val=%s, expected NULL\n", dbgstr_w(val)); + ok_(__FILE__,line) (val == NULL, "val=%s, expected NULL\n", wine_dbgstr_w(val)); } #define test_select_set_value(s,v) _test_select_set_value(__LINE__,s,v) @@ -856,7 +1068,7 @@ static void _test_select_type(unsigned line, IHTMLSelectElement *select, const c hres = IHTMLSelectElement_get_type(select, &type); ok_(__FILE__,line) (hres == S_OK, "get_type failed: %08x\n", hres); - ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", dbgstr_w(type), extype); + ok_(__FILE__,line) (!strcmp_wa(type, extype), "type=%s, expected %s\n", wine_dbgstr_w(type), extype); } #define test_range_text(r,t) _test_range_text(__LINE__,r,t) @@ -870,9 +1082,9 @@ static void _test_range_text(unsigned line, IHTMLTxtRange *range, const char *ex if(extext) { ok_(__FILE__, line) (text != NULL, "text == NULL\n"); - ok_(__FILE__, line) (!strcmp_wa(text, extext), "text=\"%s\", expected \"%s\"\n", dbgstr_w(text), extext); + ok_(__FILE__, line) (!strcmp_wa(text, extext), "text=%s, expected %s\n", wine_dbgstr_w(text), extext); }else { - ok_(__FILE__, line) (text == NULL, "text=\"%s\", expected NULL\n", dbgstr_w(text)); + ok_(__FILE__, line) (text == NULL, "text=%s, expected NULL\n", wine_dbgstr_w(text)); } SysFreeString(text); @@ -1005,13 +1217,13 @@ static void _test_elem_collection(unsigned line, IUnknown *unk, LONG len; DWORD i; VARIANT name, index; - IDispatch *disp; + IDispatch *disp, *disp2; HRESULT hres; hres = IUnknown_QueryInterface(unk, &IID_IHTMLElementCollection, (void**)&col); ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElementCollection: %08x\n", hres); - test_disp((IUnknown*)col, &DIID_DispHTMLElementCollection); + test_disp((IUnknown*)col, &DIID_DispHTMLElementCollection, "[object]"); hres = IHTMLElementCollection_get_length(col, &len); ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres); @@ -1021,9 +1233,9 @@ static void _test_elem_collection(unsigned line, IUnknown *unk, len = exlen; V_VT(&index) = VT_EMPTY; - V_VT(&name) = VT_I4; for(i=0; itest
"); + doc_write(content_doc, FALSE, "test
"); + doc_write(content_doc, TRUE, ""); hres = IHTMLDocument2_get_all(content_doc, &col); ok(hres == S_OK, "get_all failed: %08x\n", hres); @@ -4192,16 +4813,8 @@ static void test_elems(IHTMLDocument2 *doc) } elem = get_doc_elem(doc); - ok(hres == S_OK, "get_documentElement failed: %08x\n", hres); - hres = IHTMLElement_get_all(elem, &disp); + test_elem_all((IUnknown*)elem, all_types+1, sizeof(all_types)/sizeof(all_types[0])-1); IHTMLElement_Release(elem); - ok(hres == S_OK, "get_all failed: %08x\n", hres); - - hres = IDispatch_QueryInterface(disp, &IID_IHTMLElementCollection, (void**)&col); - IDispatch_Release(disp); - ok(hres == S_OK, "Could not get IHTMLElementCollection: %08x\n", hres); - test_elem_collection((IUnknown*)col, all_types+1, sizeof(all_types)/sizeof(all_types[0])-1); - IHTMLElementCollection_Release(col); get_elem_by_id(doc, "xxx", FALSE); elem = get_doc_elem_by_id(doc, "xxx"); @@ -4262,6 +4875,7 @@ static void test_elems(IHTMLDocument2 *doc) elem = get_elem_by_id(doc, "s", TRUE); if(elem) { IHTMLSelectElement *select; + IHTMLDocument2 *doc_node; hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLSelectElement, (void**)&select); ok(hres == S_OK, "Could not get IHTMLSelectElement interface: %08x\n", hres); @@ -4287,7 +4901,10 @@ static void test_elems(IHTMLDocument2 *doc) hres = IHTMLElement_get_document(elem, &disp); ok(hres == S_OK, "get_document failed: %08x\n", hres); - ok(iface_cmp((IUnknown*)disp, (IUnknown*)doc), "disp != doc\n"); + + doc_node = get_doc_node(doc); + ok(iface_cmp((IUnknown*)disp, (IUnknown*)doc_node), "disp != doc\n"); + IHTMLDocument2_Release(doc_node); IHTMLElement_Release(elem); } @@ -4306,7 +4923,7 @@ static void test_elems(IHTMLDocument2 *doc) hres = IHTMLScriptElement_get_type(script, &type); ok(hres == S_OK, "get_type failed: %08x\n", hres); - ok(!lstrcmpW(type, text_javascriptW), "Unexpected type %s\n", dbgstr_w(type)); + ok(!strcmp_wa(type, "text/javascript"), "Unexpected type %s\n", wine_dbgstr_w(type)); SysFreeString(type); /* test defer */ @@ -4361,6 +4978,9 @@ static void test_elems(IHTMLDocument2 *doc) test_input_set_checked(input, VARIANT_TRUE); test_input_set_checked(input, VARIANT_FALSE); + test_input_src(input, NULL); + test_input_set_src(input, "about:blank"); + IHTMLInputElement_Release(input); IHTMLElement_Release(elem); } @@ -4395,6 +5015,12 @@ static void test_elems(IHTMLDocument2 *doc) IHTMLElement_Release(elem); } + elem = get_elem_by_id(doc, "a", TRUE); + if(elem) { + test_anchor_href((IUnknown*)elem, "http://test/"); + IHTMLElement_Release(elem); + } + hres = IHTMLDocument2_get_body(doc, &elem); ok(hres == S_OK, "get_body failed: %08x\n", hres); @@ -4402,7 +5028,7 @@ static void test_elems(IHTMLDocument2 *doc) ok(node != NULL, "node == NULL\n"); if(node) { test_ifaces((IUnknown*)node, text_iids); - test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode); + test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]"); node2 = get_first_child((IUnknown*)node); ok(!node2, "node2 != NULL\n"); @@ -4422,7 +5048,7 @@ static void test_elems(IHTMLDocument2 *doc) if(child_col) { LONG length = 0; - test_disp((IUnknown*)child_col, &DIID_DispDOMChildrenCollection); + test_disp((IUnknown*)child_col, &DIID_DispDOMChildrenCollection, "[object]"); hres = IHTMLDOMChildrenCollection_get_length(child_col, &length); ok(hres == S_OK, "get_length failed: %08x\n", hres); @@ -4446,15 +5072,17 @@ static void test_elems(IHTMLDocument2 *doc) IHTMLDOMNode_Release(node); } - disp = (void*)0xdeadbeef; + hres = IHTMLDOMChildrenCollection_item(child_col, length - 1, NULL); + ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres); + + hres = IHTMLDOMChildrenCollection_item(child_col, length, NULL); + ok(hres == E_POINTER, "item failed: %08x, expected E_POINTER\n", hres); + hres = IHTMLDOMChildrenCollection_item(child_col, 6000, &disp); ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres); - ok(disp == (void*)0xdeadbeef, "disp=%p\n", disp); - disp = (void*)0xdeadbeef; hres = IHTMLDOMChildrenCollection_item(child_col, length, &disp); ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres); - ok(disp == (void*)0xdeadbeef, "disp=%p\n", disp); test_child_col_disp(child_col); @@ -4492,8 +5120,8 @@ static void test_elems(IHTMLDocument2 *doc) DISPID pid = -1; BSTR str = a2bstr("Testing"); hres = IDispatchEx_GetDispID(dispex, str, 1, &pid); - todo_wine ok(hres == S_OK, "GetDispID failed: %08x\n", hres); - todo_wine ok(pid != -1, "pid == -1\n"); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + ok(pid != -1, "pid == -1\n"); SysFreeString(str); IDispatchEx_Release(dispex); } @@ -4505,7 +5133,7 @@ static void test_elems(IHTMLDocument2 *doc) str = a2bstr("img"); hres = IHTMLDocument3_getElementsByTagName(doc3, str, &col); - ok(hres == S_OK, "getElementsByTagName(%s) failed: %08x\n", dbgstr_w(str), hres); + ok(hres == S_OK, "getElementsByTagName(%s) failed: %08x\n", wine_dbgstr_w(str), hres); SysFreeString(str); if(hres == S_OK) { @@ -4543,7 +5171,7 @@ static void test_create_elems(IHTMLDocument2 *doc) type = get_node_type((IUnknown*)elem); ok(type == 1, "type=%d\n", type); test_ifaces((IUnknown*)elem, elem_iids); - test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement); + test_disp((IUnknown*)elem, &DIID_DispHTMLGenericElement, "[object]"); hres = IHTMLDocument2_get_body(doc, &body); ok(hres == S_OK, "get_body failed: %08x\n", hres); @@ -4572,7 +5200,7 @@ static void test_create_elems(IHTMLDocument2 *doc) node = test_create_text(doc, "test"); test_ifaces((IUnknown*)node, text_iids); - test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode); + test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]"); V_VT(&var) = VT_NULL; node2 = test_node_insertbefore((IUnknown*)body, node, &var); @@ -4718,12 +5346,10 @@ static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, D BSTR state; HRESULT hres; - static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0}; - hres = IHTMLDocument2_get_readyState(notif_doc, &state); ok(hres == S_OK, "get_readyState failed: %08x\n", hres); - if(!lstrcmpW(state, completeW)) + if(!strcmp_wa(state, "complete")) doc_complete = TRUE; SysFreeString(state); @@ -4861,33 +5487,13 @@ static void gecko_installer_workaround(BOOL disable) RegCloseKey(hkey); } -/* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */ -/* Note: this code is duplicated in dlls/mshtml/tests/dom.c, dlls/mshtml/tests/script.c and dlls/urlmon/tests/misc.c */ -static BOOL is_ie_hardened(void) -{ - HKEY zone_map; - DWORD ie_harden, type, size; - - ie_harden = 0; - if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap", - 0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) { - size = sizeof(DWORD); - if (RegQueryValueEx(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS || - type != REG_DWORD) { - ie_harden = 0; - } - RegCloseKey(zone_map); - } - - return ie_harden != 0; -} - START_TEST(dom) { gecko_installer_workaround(TRUE); CoInitialize(NULL); run_domtest(doc_str1, test_doc_elem); + run_domtest(doc_str1, test_get_set_attr); run_domtest(range_test_str, test_txtrange); run_domtest(range_test2_str, test_txtrange2); if (winetest_interactive || ! is_ie_hardened()) { diff --git a/rostests/winetests/mshtml/events.c b/rostests/winetests/mshtml/events.c new file mode 100644 index 00000000000..d0ddadb44da --- /dev/null +++ b/rostests/winetests/mshtml/events.c @@ -0,0 +1,1554 @@ +/* + * Copyright 2008-2009 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS +#define CONST_VTABLE + +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "ole2.h" +#include "mshtml.h" +#include "docobj.h" +#include "hlink.h" +#include "dispex.h" + +#define DEFINE_EXPECT(func) \ + static BOOL expect_ ## func = FALSE, called_ ## func = FALSE + +#define SET_EXPECT(func) \ + do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0) + +#define CHECK_EXPECT2(func) \ + do { \ + trace(#func "\n"); \ + ok(expect_ ##func, "unexpected call " #func "\n"); \ + called_ ## func = TRUE; \ + }while(0) + +#define CHECK_EXPECT(func) \ + do { \ + CHECK_EXPECT2(func); \ + expect_ ## func = FALSE; \ + }while(0) + +#define CHECK_CALLED(func) \ + do { \ + ok(called_ ## func, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + +DEFINE_EXPECT(document_onclick); +DEFINE_EXPECT(body_onclick); +DEFINE_EXPECT(div_onclick); +DEFINE_EXPECT(div_onclick_attached); +DEFINE_EXPECT(timeout); + +static HWND container_hwnd = NULL; +static IHTMLWindow2 *window; +static IOleDocumentView *view; + +typedef struct { + LONG x; + LONG y; + LONG offset_x; + LONG offset_y; +} xy_test_t; + +static const xy_test_t no_xy = {-10,-10,-10,-10}; +static const xy_test_t zero_xy = {0,0,0,0}; + +static const char empty_doc_str[] = + ""; + +static const char click_doc_str[] = + "" + "
click here
" + ""; + +static const char *debugstr_w(LPCWSTR str) +{ + static char buf[1024]; + WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL); + return buf; +} + +static const char *debugstr_guid(REFIID riid) +{ + static char buf[50]; + + sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], + riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], + riid->Data4[5], riid->Data4[6], riid->Data4[7]); + + return buf; +} + +static int strcmp_wa(LPCWSTR strw, const char *stra) +{ + CHAR buf[512]; + WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); + return lstrcmpA(stra, buf); +} + +static BSTR a2bstr(const char *str) +{ + BSTR ret; + int len; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = SysAllocStringLen(NULL, len-1); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + + return ret; +} + +static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2) +{ + IUnknown *unk1, *unk2; + + if(iface1 == iface2) + return TRUE; + + IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk1); + IUnknown_Release(unk1); + IUnknown_QueryInterface(iface1, &IID_IUnknown, (void**)&unk2); + IUnknown_Release(unk2); + + return unk1 == unk2; +} + +#define test_disp(u,id) _test_disp(__LINE__,u,id) +static void _test_disp(unsigned line, IUnknown *unk, const IID *diid) +{ + IDispatchEx *dispex; + ITypeInfo *typeinfo; + UINT ticnt; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex); + ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres); + if(FAILED(hres)) + return; + + ticnt = 0xdeadbeef; + hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt); + ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres); + ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt); + + hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo); + ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres); + + if(SUCCEEDED(hres)) { + TYPEATTR *type_attr; + + hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr); + ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres); + ok_(__FILE__,line) (IsEqualGUID(&type_attr->guid, diid), "unexpected guid %s\n", + debugstr_guid(&type_attr->guid)); + + ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr); + ITypeInfo_Release(typeinfo); + } + + IDispatchEx_Release(dispex); +} + +#define get_doc3_iface(u) _get_doc3_iface(__LINE__,u) +static IHTMLDocument3 *_get_doc3_iface(unsigned line, IUnknown *unk) +{ + IHTMLDocument3 *doc3; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument3, (void**)&doc3); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres); + + return doc3; +} + +#define get_elem_iface(u) _get_elem_iface(__LINE__,u) +static IHTMLElement *_get_elem_iface(unsigned line, IUnknown *unk) +{ + IHTMLElement *elem; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement, (void**)&elem); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement iface: %08x\n", hres); + + return elem; +} + +#define get_elem2_iface(u) _get_elem2_iface(__LINE__,u) +static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk) +{ + IHTMLElement2 *elem2; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement2, (void**)&elem2); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement2 iface: %08x\n", hres); + + return elem2; +} + +#define doc_get_body(d) _doc_get_body(__LINE__,d) +static IHTMLElement *_doc_get_body(unsigned line, IHTMLDocument2 *doc) +{ + IHTMLElement *body = NULL; + HRESULT hres; + + hres = IHTMLDocument2_get_body(doc, &body); + ok_(__FILE__,line) (hres == S_OK, "get_body failed: %08x\n", hres); + ok_(__FILE__,line) (body != NULL, "body == NULL\n"); + + return body; +} + +#define get_elem_id(d,i) _get_elem_id(__LINE__,d,i) +static IHTMLElement *_get_elem_id(unsigned line, IHTMLDocument2 *doc, const char *id) +{ + IHTMLDocument3 *doc3 = _get_doc3_iface(line, (IUnknown*)doc); + IHTMLElement *elem; + BSTR str; + HRESULT hres; + + str = a2bstr(id); + hres = IHTMLDocument3_getElementById(doc3, str, &elem); + SysFreeString(str); + IHTMLDocument3_Release(doc3); + ok_(__FILE__,line) (hres == S_OK, "getElementById failed: %08x\n", hres); + + return elem; +} + +#define test_elem_tag(u,n) _test_elem_tag(__LINE__,u,n) +static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag) +{ + IHTMLElement *elem = _get_elem_iface(line, unk); + BSTR tag; + HRESULT hres; + + hres = IHTMLElement_get_tagName(elem, &tag); + IHTMLElement_Release(elem); + ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres); + ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", debugstr_w(tag), extag); + + SysFreeString(tag); +} + +#define get_event_obj() _get_event_obj(__LINE__) +static IHTMLEventObj *_get_event_obj(unsigned line) +{ + IHTMLEventObj *event = NULL; + HRESULT hres; + + hres = IHTMLWindow2_get_event(window, &event); + ok_(__FILE__,line) (hres == S_OK, "get_event failed: %08x\n", hres); + ok_(__FILE__,line) (event != NULL, "event = NULL\n"); + _test_disp(line, (IUnknown*)event, &DIID_DispCEventObj); + + return event; +} + +#define test_event_args(a,b,c,d,e,f,g) _test_event_args(__LINE__,a,b,c,d,e,f,g) +static void _test_event_args(unsigned line, const IID *dispiid, DISPID id, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + ok_(__FILE__,line) (id == DISPID_VALUE, "id = %d\n", id); + ok_(__FILE__,line) (wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags); + ok_(__FILE__,line) (pdp != NULL, "pdp == NULL\n"); + ok_(__FILE__,line) (pdp->cArgs == 1, "pdp->cArgs = %d\n", pdp->cArgs); + ok_(__FILE__,line) (pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs); + ok_(__FILE__,line) (pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", + pdp->rgdispidNamedArgs[0]); + ok_(__FILE__,line) (V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg)); + ok_(__FILE__,line) (pvarRes != NULL, "pvarRes == NULL\n"); + ok_(__FILE__,line) (pei != NULL, "pei == NULL"); + ok_(__FILE__,line) (!pspCaller, "pspCaller != NULL\n"); + + if(dispiid) + _test_disp(line, (IUnknown*)V_DISPATCH(pdp->rgvarg), dispiid); +} + +#define test_attached_event_args(a,b,c,d,e) _test_attached_event_args(__LINE__,a,b,c,d,e) +static void _test_attached_event_args(unsigned line, DISPID id, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei) +{ + IHTMLEventObj *event; + + ok(id == DISPID_VALUE, "id = %d\n", id); + ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pDispParams == NULL\n"); + ok(pdp->cArgs == 1, "pdp->cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs); + ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs = %p\n", pdp->rgdispidNamedArgs); + ok(pdp->rgvarg != NULL, "rgvarg = NULL\n"); + ok(pvarRes != NULL, "pvarRes = NULL\n"); + ok(pei != NULL, "pei = NULL\n"); + ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pVarRes) = %d\n", V_VT(pvarRes)); + ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(pdp->rgvarg) = %d\n", V_VT(pdp->rgvarg)); + ok(V_DISPATCH(pdp->rgvarg) != NULL, "V_DISPATCH(pdp->rgvarg) = %p\n", V_DISPATCH(pdp->rgvarg)); + + event = _get_event_obj(line); + ok(iface_cmp((IUnknown*)event, (IUnknown*)V_DISPATCH(pdp->rgvarg)), "event != arg0\n"); + IHTMLEventObj_Release(event); +} + +#define test_event_src(t) _test_event_src(__LINE__,t) +static void _test_event_src(unsigned line, const char *src_tag) +{ + IHTMLEventObj *event = _get_event_obj(line); + IHTMLElement *src_elem = NULL; + HRESULT hres; + + hres = IHTMLEventObj_get_srcElement(event, &src_elem); + IHTMLEventObj_Release(event); + ok_(__FILE__,line) (hres == S_OK, "get_srcElement failed: %08x\n", hres); + + if(src_tag) { + ok_(__FILE__,line) (src_elem != NULL, "src_elem = NULL\n"); + _test_elem_tag(line, (IUnknown*)src_elem, src_tag); + IHTMLElement_Release(src_elem); + }else { + ok_(__FILE__,line) (!src_elem, "src_elem != NULL\n"); + } +} + +static void _test_event_altkey(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval) +{ + VARIANT_BOOL b; + HRESULT hres; + + hres = IHTMLEventObj_get_altKey(event, &b); + ok_(__FILE__,line)(hres == S_OK, "get_altKey failed: %08x\n", hres); + ok_(__FILE__,line)(b == exval, "altKey = %x, expected %x\n", b, exval); +} + +static void _test_event_ctrlkey(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval) +{ + VARIANT_BOOL b; + HRESULT hres; + + hres = IHTMLEventObj_get_ctrlKey(event, &b); + ok_(__FILE__,line)(hres == S_OK, "get_ctrlKey failed: %08x\n", hres); + ok_(__FILE__,line)(b == exval, "ctrlKey = %x, expected %x\n", b, exval); +} + +static void _test_event_shiftkey(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval) +{ + VARIANT_BOOL b; + HRESULT hres; + + hres = IHTMLEventObj_get_shiftKey(event, &b); + ok_(__FILE__,line)(hres == S_OK, "get_shiftKey failed: %08x\n", hres); + ok_(__FILE__,line)(b == exval, "shiftKey = %x, expected %x\n", b, exval); +} + +static void _test_event_cancelbubble(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval) +{ + VARIANT_BOOL b; + HRESULT hres; + + hres = IHTMLEventObj_get_cancelBubble(event, &b); + ok_(__FILE__,line)(hres == S_OK, "get_cancelBubble failed: %08x\n", hres); + ok_(__FILE__,line)(b == exval, "cancelBubble = %x, expected %x\n", b, exval); +} + +static void _test_event_fromelem(unsigned line, IHTMLEventObj *event, const char *from_tag) +{ + IHTMLElement *elem; + HRESULT hres; + + hres = IHTMLEventObj_get_fromElement(event, &elem); + ok_(__FILE__,line)(hres == S_OK, "get_fromElement failed: %08x\n", hres); + if(from_tag) + _test_elem_tag(line, (IUnknown*)elem, from_tag); + else + ok_(__FILE__,line)(elem == NULL, "fromElement != NULL\n"); + if(elem) + IHTMLElement_Release(elem); +} + +static void _test_event_toelem(unsigned line, IHTMLEventObj *event, const char *to_tag) +{ + IHTMLElement *elem; + HRESULT hres; + + hres = IHTMLEventObj_get_toElement(event, &elem); + ok_(__FILE__,line)(hres == S_OK, "get_toElement failed: %08x\n", hres); + if(to_tag) + _test_elem_tag(line, (IUnknown*)elem, to_tag); + else + ok_(__FILE__,line)(elem == NULL, "toElement != NULL\n"); + if(elem) + IHTMLElement_Release(elem); +} + +static void _test_event_keycode(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_keyCode(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_keyCode failed: %08x\n", hres); + ok_(__FILE__,line)(l == exl, "keyCode = %x, expected %x\n", l, exl); +} + +static void _test_event_button(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_button(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_button failed: %08x\n", hres); + ok_(__FILE__,line)(l == exl, "button = %x, expected %x\n", l, exl); +} + +static void _test_event_reason(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_reason(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_reason failed: %08x\n", hres); + ok_(__FILE__,line)(l == exl, "reason = %x, expected %x\n", l, exl); +} + +static void _test_event_x(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_x(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_x failed: %08x\n", hres); + if(exl == -10) /* don't test the exact value */ + todo_wine ok_(__FILE__,line)(l > 0, "x = %d\n", l); + else + ok_(__FILE__,line)(l == exl, "x = %d, expected %d\n", l, exl); +} + +static void _test_event_y(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_y(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_y failed: %08x\n", hres); + if(exl == -10) /* don't test the exact value */ + todo_wine ok_(__FILE__,line)(l > 0, "y = %d\n", l); + else + ok_(__FILE__,line)(l == exl, "y = %d, expected %d\n", l, exl); +} + +static void _test_event_clientx(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_clientX(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_clientX failed: %08x\n", hres); + if(exl == -10) /* don't test the exact value */ + ok_(__FILE__,line)(l > 0, "clientX = %d\n", l); + else + ok_(__FILE__,line)(l == exl, "clientX = %d, expected %d\n", l, exl); +} + +static void _test_event_clienty(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_clientY(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_clientY failed: %08x\n", hres); + if(exl == -10) /* don't test the exact value */ + ok_(__FILE__,line)(l > 0, "clientY = %d\n", l); + else + ok_(__FILE__,line)(l == exl, "clientY = %d, expected %d\n", l, exl); +} + +static void _test_event_offsetx(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_offsetX(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_offsetX failed: %08x\n", hres); + if(exl == -10) /* don't test the exact value */ + todo_wine ok_(__FILE__,line)(l > 0, "offsetX = %d\n", l); + else + ok_(__FILE__,line)(l == exl, "offsetX = %d, expected %d\n", l, exl); +} + +static void _test_event_offsety(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_offsetY(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_offsetY failed: %08x\n", hres); + if(exl == -10) /* don't test the exact value */ + todo_wine ok_(__FILE__,line)(l > 0, "offsetY = %d\n", l); + else + ok_(__FILE__,line)(l == exl, "offsetY = %d, expected %d\n", l, exl); +} + +static void _test_event_screenx(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_screenX(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_screenX failed: %08x\n", hres); + if(exl == -10) /* don't test the exact value */ + ok_(__FILE__,line)(l > 0, "screenX = %d\n", l); + else + ok_(__FILE__,line)(l == exl, "screenX = %d, expected %d\n", l, exl); +} + +static void _test_event_screeny(unsigned line, IHTMLEventObj *event, LONG exl) +{ + LONG l; + HRESULT hres; + + hres = IHTMLEventObj_get_screenY(event, &l); + ok_(__FILE__,line)(hres == S_OK, "get_screenY failed: %08x\n", hres); + if(exl == -10) /* don't test the exact value */ + ok_(__FILE__,line)(l > 0, "screenY = %d\n", l); + else + ok_(__FILE__,line)(l == exl, "screenY = %d, expected %d\n", l, exl); +} + +static void _test_event_type(unsigned line, IHTMLEventObj *event, const char *exstr) +{ + BSTR str; + HRESULT hres; + + hres = IHTMLEventObj_get_type(event, &str); + ok_(__FILE__,line)(hres == S_OK, "get_type failed: %08x\n", hres); + ok_(__FILE__,line)(!strcmp_wa(str, exstr), "type = %s, expected %s\n", wine_dbgstr_w(str), exstr); +} + +static void _test_event_qualifier(unsigned line, IHTMLEventObj *event, const char *exstr) +{ + BSTR str; + HRESULT hres; + + hres = IHTMLEventObj_get_qualifier(event, &str); + ok_(__FILE__,line)(hres == S_OK, "get_qualifier failed: %08x\n", hres); + if(exstr) + ok_(__FILE__,line)(!strcmp_wa(str, exstr), "qualifier = %s, expected %s\n", wine_dbgstr_w(str), exstr); + else + ok_(__FILE__,line)(!str, "qualifier != NULL\n"); +} + +static void _test_event_srcfilter(unsigned line, IHTMLEventObj *event) +{ + IDispatch *disp; + HRESULT hres; + + hres = IHTMLEventObj_get_srcFilter(event, &disp); + ok_(__FILE__,line)(hres == S_OK, "get_srcFilter failed: %08x\n", hres); + ok_(__FILE__,line)(!disp, "srcFilter != NULL\n"); +} + +#define test_event_obj(t,x) _test_event_obj(__LINE__,t,x) +static void _test_event_obj(unsigned line, const char *type, const xy_test_t *xy) +{ + IHTMLEventObj *event = _get_event_obj(line); + VARIANT v; + HRESULT hres; + + _test_event_altkey(line, event, VARIANT_FALSE); + _test_event_ctrlkey(line, event, VARIANT_FALSE); + _test_event_shiftkey(line, event, VARIANT_FALSE); + _test_event_cancelbubble(line, event, VARIANT_FALSE); + _test_event_fromelem(line, event, NULL); + _test_event_toelem(line, event, NULL); + _test_event_keycode(line, event, 0); + _test_event_button(line, event, 0); + _test_event_type(line, event, type); + _test_event_qualifier(line, event, NULL); + _test_event_reason(line, event, 0); + _test_event_srcfilter(line, event); + _test_event_x(line, event, xy->x); + _test_event_y(line, event, xy->y); + _test_event_clientx(line, event, -10); + _test_event_clienty(line, event, -10); + _test_event_offsetx(line, event, xy->offset_x); + _test_event_offsety(line, event, xy->offset_y); + _test_event_screenx(line, event, -10); + _test_event_screeny(line, event, -10); + + hres = IHTMLEventObj_get_returnValue(event, &v); + ok_(__FILE__,line)(hres == S_OK, "get_returnValue failed: %08x\n", hres); + ok_(__FILE__,line)(V_VT(&v) == VT_EMPTY, "V_VT(returnValue) = %d\n", V_VT(&v)); + + IHTMLEventObj_Release(event); +} + +#define elem_attach_event(a,b,c) _elem_attach_event(__LINE__,a,b,c) +static void _elem_attach_event(unsigned line, IUnknown *unk, const char *namea, IDispatch *disp) +{ + IHTMLElement2 *elem = _get_elem2_iface(line, unk); + VARIANT_BOOL res; + BSTR name; + HRESULT hres; + + name = a2bstr(namea); + hres = IHTMLElement2_attachEvent(elem, name, disp, &res); + IHTMLElement2_Release(elem); + SysFreeString(name); + ok_(__FILE__,line)(hres == S_OK, "attachEvent failed: %08x\n", hres); + ok_(__FILE__,line)(res == VARIANT_TRUE, "attachEvent returned %x\n", res); +} + +static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDispatch) + || IsEqualGUID(riid, &IID_IDispatchEx)) + *ppv = iface; + else { + ok(0, "unexpected riid %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + return S_OK; +} + +static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface) +{ + return 2; +} + +static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface) +{ + return 1; +} + +static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) +{ + ok(0, "unexpected call %s %x\n", debugstr_w(bstrName), grfdex); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +#define EVENT_HANDLER_FUNC_OBJ(event) \ + static IDispatchExVtbl event ## FuncVtbl = { \ + DispatchEx_QueryInterface, \ + DispatchEx_AddRef, \ + DispatchEx_Release, \ + DispatchEx_GetTypeInfoCount, \ + DispatchEx_GetTypeInfo, \ + DispatchEx_GetIDsOfNames, \ + DispatchEx_Invoke, \ + DispatchEx_GetDispID, \ + event, \ + DispatchEx_DeleteMemberByName, \ + DispatchEx_DeleteMemberByDispID, \ + DispatchEx_GetMemberProperties, \ + DispatchEx_GetMemberName, \ + DispatchEx_GetNextDispID, \ + DispatchEx_GetNameSpaceParent \ + }; \ + static IDispatchEx event ## _obj = { &event ## FuncVtbl }; + +static HRESULT WINAPI document_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + IHTMLDocument3 *doc3; + CHECK_EXPECT(document_onclick); + test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller); + doc3 = get_doc3_iface((IUnknown*)V_DISPATCH(pdp->rgvarg)); + IHTMLDocument3_Release(doc3); + test_event_src("DIV"); + test_event_obj("click", &no_xy); + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(document_onclick); + +static HRESULT WINAPI div_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + CHECK_EXPECT(div_onclick); + test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller); + test_event_src("DIV"); + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(div_onclick); + +static HRESULT WINAPI div_onclick_attached(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + CHECK_EXPECT(div_onclick_attached); + + test_attached_event_args(id, wFlags, pdp, pvarRes, pei); + test_event_src("DIV"); + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(div_onclick_attached); + +static HRESULT WINAPI body_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + CHECK_EXPECT(body_onclick); + test_event_args(&DIID_DispHTMLBody, id, wFlags, pdp, pvarRes, pei, pspCaller); + test_event_src("DIV"); + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(body_onclick); + +static HRESULT WINAPI nocall(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + ok(0, "unexpected call\n"); + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(nocall); + +static HRESULT WINAPI timeoutFunc_Invoke(IDispatchEx *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + CHECK_EXPECT(timeout); + + ok(dispIdMember == DISPID_VALUE, "dispIdMember = %d\n", dispIdMember); + ok(IsEqualGUID(&IID_NULL, riid), "riid = %s\n", debugstr_guid(riid)); + ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags); + ok(!lcid, "lcid = %x\n", lcid); + ok(pDispParams != NULL, "pDispParams == NULL\n"); + ok(!pDispParams->cArgs, "pdp->cArgs = %d\n", pDispParams->cArgs); + ok(!pDispParams->cNamedArgs, "pdp->cNamedArgs = %d\n", pDispParams->cNamedArgs); + ok(!pDispParams->rgdispidNamedArgs, "pdp->rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs); + ok(!pDispParams->rgvarg, "rgvarg = %p\n", pDispParams->rgvarg); + ok(pVarResult != NULL, "pVarResult = NULL\n"); + ok(pExcepInfo != NULL, "pExcepInfo = NULL\n"); + ok(!puArgErr, "puArgErr = %p\n", puArgErr); + ok(V_VT(pVarResult) == VT_EMPTY, "V_VT(pVarResult) = %d\n", V_VT(pVarResult)); + + return S_OK; +} + +static IDispatchExVtbl timeoutFuncVtbl = { + DispatchEx_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + timeoutFunc_Invoke, + DispatchEx_GetDispID, + DispatchEx_InvokeEx, + DispatchEx_DeleteMemberByName, + DispatchEx_DeleteMemberByDispID, + DispatchEx_GetMemberProperties, + DispatchEx_GetMemberName, + DispatchEx_GetNextDispID, + DispatchEx_GetNameSpaceParent +}; + +static IDispatchEx timeoutFunc = { &timeoutFuncVtbl }; + +static void pump_msgs(BOOL *b) +{ + MSG msg; + while(!*b && GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +static void test_onclick(IHTMLDocument2 *doc) +{ + IHTMLElement *div, *body; + VARIANT v; + HRESULT hres; + + div = get_elem_id(doc, "clickdiv"); + + elem_attach_event((IUnknown*)div, "abcde", (IDispatch*)&nocall_obj); + elem_attach_event((IUnknown*)div, "onclick", (IDispatch*)&div_onclick_attached_obj); + + V_VT(&v) = VT_EMPTY; + hres = IHTMLElement_get_onclick(div, &v); + ok(hres == S_OK, "get_onclick failed: %08x\n", hres); + ok(V_VT(&v) == VT_NULL, "V_VT(onclick) = %d\n", V_VT(&v)); + + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)&div_onclick_obj; + hres = IHTMLElement_put_onclick(div, v); + ok(hres == S_OK, "put_onclick failed: %08x\n", hres); + + V_VT(&v) = VT_EMPTY; + hres = IHTMLElement_get_onclick(div, &v); + ok(hres == S_OK, "get_onclick failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(onclick) = %d\n", V_VT(&v)); + ok(V_DISPATCH(&v) == (IDispatch*)&div_onclick_obj, "V_DISPATCH(onclick) != onclickFunc\n"); + VariantClear(&v); + + V_VT(&v) = VT_EMPTY; + hres = IHTMLDocument2_get_onclick(doc, &v); + ok(hres == S_OK, "get_onclick failed: %08x\n", hres); + ok(V_VT(&v) == VT_NULL, "V_VT(onclick) = %d\n", V_VT(&v)); + + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)&document_onclick_obj; + hres = IHTMLDocument2_put_onclick(doc, v); + ok(hres == S_OK, "put_onclick failed: %08x\n", hres); + + V_VT(&v) = VT_EMPTY; + hres = IHTMLDocument2_get_onclick(doc, &v); + ok(hres == S_OK, "get_onclick failed: %08x\n", hres); + ok(V_VT(&v) == VT_DISPATCH, "V_VT(onclick) = %d\n", V_VT(&v)); + ok(V_DISPATCH(&v) == (IDispatch*)&document_onclick_obj, "V_DISPATCH(onclick) != onclickFunc\n"); + VariantClear(&v); + + body = doc_get_body(doc); + + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)&body_onclick_obj; + hres = IHTMLElement_put_onclick(body, v); + ok(hres == S_OK, "put_onclick failed: %08x\n", hres); + + if(winetest_interactive) { + SET_EXPECT(div_onclick); + SET_EXPECT(div_onclick_attached); + SET_EXPECT(body_onclick); + SET_EXPECT(document_onclick); + pump_msgs(&called_document_onclick); + CHECK_CALLED(div_onclick); + CHECK_CALLED(div_onclick_attached); + CHECK_CALLED(body_onclick); + CHECK_CALLED(document_onclick); + } + + IHTMLElement_Release(div); + IHTMLElement_Release(body); +} + +static void test_timeout(IHTMLDocument2 *doc) +{ + IHTMLWindow3 *win3; + VARIANT expr, var; + LONG id; + HRESULT hres; + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow3, (void**)&win3); + ok(hres == S_OK, "Could not get IHTMLWindow3 iface: %08x\n", hres); + + V_VT(&expr) = VT_DISPATCH; + V_DISPATCH(&expr) = (IDispatch*)&timeoutFunc; + V_VT(&var) = VT_EMPTY; + id = 0; + hres = IHTMLWindow3_setTimeout(win3, &expr, 0, &var, &id); + ok(hres == S_OK, "setTimeout failed: %08x\n", hres); + ok(id, "id = 0\n"); + + SET_EXPECT(timeout); + pump_msgs(&called_timeout); + CHECK_CALLED(timeout); + + V_VT(&expr) = VT_DISPATCH; + V_DISPATCH(&expr) = (IDispatch*)&timeoutFunc; + V_VT(&var) = VT_EMPTY; + id = 0; + hres = IHTMLWindow3_setTimeout(win3, &expr, 0, &var, &id); + ok(hres == S_OK, "setTimeout failed: %08x\n", hres); + ok(id, "id = 0\n"); + + hres = IHTMLWindow2_clearTimeout(window, id); + ok(hres == S_OK, "clearTimeout failed: %08x\n", hres); + + IHTMLWindow3_Release(win3); +} + +static HRESULT QueryInterface(REFIID,void**); + +static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv) +{ + return E_NOINTERFACE; +} + +static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface) +{ + return 2; +} + +static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface) +{ + return 1; +} + +static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface, + LPCBORDERWIDTHS pborderwidths) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface, + LPCBORDERWIDTHS pborderwidths) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface, + IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface, + IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared, + LPOLEMENUGROUPWIDTHS lpMenuWidths) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared, + HOLEMENU holemenu, HWND hwndActiveObject) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = { + InPlaceFrame_QueryInterface, + InPlaceFrame_AddRef, + InPlaceFrame_Release, + InPlaceFrame_GetWindow, + InPlaceFrame_ContextSensitiveHelp, + InPlaceFrame_GetBorder, + InPlaceFrame_RequestBorderSpace, + InPlaceFrame_SetBorderSpace, + InPlaceFrame_SetActiveObject, + InPlaceFrame_InsertMenus, + InPlaceFrame_SetMenu, + InPlaceFrame_RemoveMenus, + InPlaceFrame_SetStatusText, + InPlaceFrame_EnableModeless, + InPlaceFrame_TranslateAccelerator +}; + +static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl }; + +static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = { + InPlaceFrame_QueryInterface, + InPlaceFrame_AddRef, + InPlaceFrame_Release, + InPlaceFrame_GetWindow, + InPlaceFrame_ContextSensitiveHelp, + InPlaceFrame_GetBorder, + InPlaceFrame_RequestBorderSpace, + InPlaceFrame_SetBorderSpace, + InPlaceUIWindow_SetActiveObject, +}; + +static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl }; + +static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv) +{ + return QueryInterface(riid, ppv); +} + +static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface) +{ + return 2; +} + +static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface) +{ + return 1; +} + +static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd) +{ + *phwnd = container_hwnd; + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface, + IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, + LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) +{ + static const RECT rect = {0,0,300,300}; + + *ppFrame = &InPlaceFrame; + *ppDoc = (IOleInPlaceUIWindow*)&InPlaceUIWindow; + *lprcPosRect = rect; + *lprcClipRect = rect; + + lpFrameInfo->cb = sizeof(*lpFrameInfo); + lpFrameInfo->fMDIApp = FALSE; + lpFrameInfo->hwndFrame = container_hwnd; + lpFrameInfo->haccel = NULL; + lpFrameInfo->cAccelEntries = 0; + + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface) +{ + return S_OK; +} + +static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect) +{ + return E_NOTIMPL; +} + +static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = { + InPlaceSite_QueryInterface, + InPlaceSite_AddRef, + InPlaceSite_Release, + InPlaceSite_GetWindow, + InPlaceSite_ContextSensitiveHelp, + InPlaceSite_CanInPlaceActivate, + InPlaceSite_OnInPlaceActivate, + InPlaceSite_OnUIActivate, + InPlaceSite_GetWindowContext, + InPlaceSite_Scroll, + InPlaceSite_OnUIDeactivate, + InPlaceSite_OnInPlaceDeactivate, + InPlaceSite_DiscardUndoState, + InPlaceSite_DeactivateAndUndo, + InPlaceSite_OnPosRectChange, +}; + +static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl }; + +static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv) +{ + return QueryInterface(riid, ppv); +} + +static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface) +{ + return 2; +} + +static ULONG WINAPI ClientSite_Release(IOleClientSite *iface) +{ + return 1; +} + +static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker, + IMoniker **ppmon) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IOleClientSiteVtbl ClientSiteVtbl = { + ClientSite_QueryInterface, + ClientSite_AddRef, + ClientSite_Release, + ClientSite_SaveObject, + ClientSite_GetMoniker, + ClientSite_GetContainer, + ClientSite_ShowObject, + ClientSite_OnShowWindow, + ClientSite_RequestNewObjectLayout +}; + +static IOleClientSite ClientSite = { &ClientSiteVtbl }; + +static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv) +{ + return QueryInterface(riid, ppv); +} + +static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface) +{ + return 2; +} + +static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface) +{ + return 1; +} + +static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate) +{ + RECT rect = {0,0,300,300}; + IOleDocument *document; + HRESULT hres; + + hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document); + ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres); + + hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view); + IOleDocument_Release(document); + ok(hres == S_OK, "CreateView failed: %08x\n", hres); + + hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite); + ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres); + + hres = IOleDocumentView_UIActivate(view, TRUE); + ok(hres == S_OK, "UIActivate failed: %08x\n", hres); + + hres = IOleDocumentView_SetRect(view, &rect); + ok(hres == S_OK, "SetRect failed: %08x\n", hres); + + hres = IOleDocumentView_Show(view, TRUE); + ok(hres == S_OK, "Show failed: %08x\n", hres); + + return S_OK; +} + +static const IOleDocumentSiteVtbl DocumentSiteVtbl = { + DocumentSite_QueryInterface, + DocumentSite_AddRef, + DocumentSite_Release, + DocumentSite_ActivateMe +}; + +static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl }; + +static HRESULT QueryInterface(REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid)) + *ppv = &ClientSite; + else if(IsEqualGUID(&IID_IOleDocumentSite, riid)) + *ppv = &DocumentSite; + else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid)) + *ppv = &InPlaceSite; + + return *ppv ? S_OK : E_NOINTERFACE; +} + +static IHTMLDocument2 *notif_doc; +static BOOL doc_complete; + +static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, + REFIID riid, void**ppv) +{ + if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) { + *ppv = iface; + return S_OK; + } + + ok(0, "unexpected call\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface) +{ + return 2; +} + +static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface) +{ + return 1; +} + +static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID) +{ + if(dispID == DISPID_READYSTATE){ + BSTR state; + HRESULT hres; + + hres = IHTMLDocument2_get_readyState(notif_doc, &state); + ok(hres == S_OK, "get_readyState failed: %08x\n", hres); + + if(!strcmp_wa(state, "complete")) + doc_complete = TRUE; + + SysFreeString(state); + } + + return S_OK; +} + +static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = { + PropertyNotifySink_QueryInterface, + PropertyNotifySink_AddRef, + PropertyNotifySink_Release, + PropertyNotifySink_OnChanged, + PropertyNotifySink_OnRequestEdit +}; + +static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl }; + +static void doc_load_string(IHTMLDocument2 *doc, const char *str) +{ + IPersistStreamInit *init; + IStream *stream; + HGLOBAL mem; + SIZE_T len; + + notif_doc = doc; + + doc_complete = FALSE; + len = strlen(str); + mem = GlobalAlloc(0, len); + memcpy(mem, str, len); + CreateStreamOnHGlobal(mem, TRUE, &stream); + + IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init); + + IPersistStreamInit_Load(init, stream); + IPersistStreamInit_Release(init); + IStream_Release(stream); +} + +static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise) +{ + IConnectionPointContainer *container; + IConnectionPoint *cp; + DWORD cookie; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container); + ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres); + + hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp); + IConnectionPointContainer_Release(container); + ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres); + + hres = IConnectionPoint_Advise(cp, unk_advise, &cookie); + IConnectionPoint_Release(cp); + ok(hres == S_OK, "Advise failed: %08x\n", hres); +} + +static void set_client_site(IHTMLDocument2 *doc, BOOL set) +{ + IOleObject *oleobj; + HRESULT hres; + + if(!set && view) { + IOleDocumentView_Show(view, FALSE); + IOleDocumentView_CloseView(view, 0); + IOleDocumentView_SetInPlaceSite(view, NULL); + IOleDocumentView_Release(view); + view = NULL; + } + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj); + ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres); + + hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL); + ok(hres == S_OK, "SetClientSite failed: %08x\n", hres); + + if(set) { + IHlinkTarget *hlink; + + hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink); + ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres); + + hres = IHlinkTarget_Navigate(hlink, 0, NULL); + ok(hres == S_OK, "Navgate failed: %08x\n", hres); + + IHlinkTarget_Release(hlink); + } + + IOleObject_Release(oleobj); +} +static IHTMLDocument2 *create_document(void) +{ + IHTMLDocument2 *doc; + HRESULT hres; + + hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IHTMLDocument2, (void**)&doc); + ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres); + + return doc; +} + + +typedef void (*testfunc_t)(IHTMLDocument2*); + +static void run_test(const char *str, testfunc_t test) +{ + IHTMLDocument2 *doc; + IHTMLElement *body = NULL; + ULONG ref; + MSG msg; + HRESULT hres; + + doc = create_document(); + set_client_site(doc, TRUE); + doc_load_string(doc, str); + do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink); + + while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + hres = IHTMLDocument2_get_body(doc, &body); + ok(hres == S_OK, "get_body failed: %08x\n", hres); + + if(body) { + IHTMLElement_Release(body); + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres); + ok(window != NULL, "window == NULL\n"); + + test(doc); + + IHTMLWindow2_Release(window); + window = NULL; + }else { + skip("Could not get document body. Assuming no Gecko installed.\n"); + } + + set_client_site(doc, FALSE); + ref = IHTMLDocument2_Release(doc); + ok(!ref, "ref = %d\n", ref); +} + +static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +static HWND create_container_window(void) +{ + static const CHAR szHTMLDocumentTest[] = "HTMLDocumentTest"; + static WNDCLASSEXA wndclass = { + sizeof(WNDCLASSEXA), + 0, + wnd_proc, + 0, 0, NULL, NULL, NULL, NULL, NULL, + szHTMLDocumentTest, + NULL + }; + + RegisterClassExA(&wndclass); + return CreateWindowA(szHTMLDocumentTest, szHTMLDocumentTest, + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, + 300, 300, NULL, NULL, NULL, NULL); +} + +START_TEST(events) +{ + CoInitialize(NULL); + container_hwnd = create_container_window(); + + if(winetest_interactive) + ShowWindow(container_hwnd, SW_SHOW); + + run_test(empty_doc_str, test_timeout); + run_test(click_doc_str, test_onclick); + + DestroyWindow(container_hwnd); + CoUninitialize(); +} diff --git a/rostests/winetests/mshtml/htmldoc.c b/rostests/winetests/mshtml/htmldoc.c index 60b3d2e2cf8..7a4d5eeeeaa 100644 --- a/rostests/winetests/mshtml/htmldoc.c +++ b/rostests/winetests/mshtml/htmldoc.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Jacek Caban for CodeWeavers + * Copyright 2005-2009 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,6 +37,7 @@ #include "idispids.h" #include "shlguid.h" #include "perhist.h" +#include "mshtml_test.h" DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); DEFINE_GUID(IID_IProxyManager,0x00000008,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); @@ -104,6 +105,7 @@ DEFINE_EXPECT(Exec_ShellDocView_37); DEFINE_EXPECT(Exec_ShellDocView_84); DEFINE_EXPECT(Exec_ShellDocView_103); DEFINE_EXPECT(Exec_ShellDocView_105); +DEFINE_EXPECT(Exec_ShellDocView_140); DEFINE_EXPECT(Exec_UPDATECOMMANDS); DEFINE_EXPECT(Exec_SETTITLE); DEFINE_EXPECT(Exec_HTTPEQUIV); @@ -121,6 +123,7 @@ DEFINE_EXPECT(Navigate); DEFINE_EXPECT(OnFrameWindowActivate); DEFINE_EXPECT(OnChanged_READYSTATE); DEFINE_EXPECT(OnChanged_1005); +DEFINE_EXPECT(OnChanged_1012); DEFINE_EXPECT(GetDisplayName); DEFINE_EXPECT(BindToStorage); DEFINE_EXPECT(IsSystemMoniker); @@ -144,8 +147,10 @@ DEFINE_EXPECT(EnableModeless_TRUE); DEFINE_EXPECT(EnableModeless_FALSE); DEFINE_EXPECT(Frame_EnableModeless_TRUE); DEFINE_EXPECT(Frame_EnableModeless_FALSE); +DEFINE_EXPECT(Frame_GetWindow); static IUnknown *doc_unk; +static IMoniker *doc_mon; static BOOL expect_LockContainer_fLock; static BOOL expect_InPlaceUIWindow_SetActiveObject_active = TRUE; static BOOL ipsex; @@ -182,8 +187,6 @@ static BOOL nogecko = FALSE; #define test_readyState(u) _test_readyState(__LINE__,u) static void _test_readyState(unsigned,IUnknown*); -static void test_GetCurMoniker(IUnknown*,IMoniker*,LPCWSTR); - static const WCHAR wszTimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n',0}; static const WCHAR wszArial[] = @@ -201,15 +204,17 @@ static const char *debugstr_guid(REFIID riid) return buf; } -static const char *debugstr_w(LPCWSTR str) +static int strcmp_wa(LPCWSTR strw, const char *stra) { - static char buf[1024]; + CHAR buf[512]; + WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); + return lstrcmpA(stra, buf); +} - if(!str) - return "(null)"; - - WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL); - return buf; +static BOOL is_english(void) +{ + return PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH + && PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH; } #define EXPECT_UPDATEUI 1 @@ -241,6 +246,75 @@ static void test_timer(DWORD flags) CHECK_CALLED(Exec_SETTITLE); } +static IMoniker Moniker; + +#define test_GetCurMoniker(u,m,v) _test_GetCurMoniker(__LINE__,u,m,v) +static void _test_GetCurMoniker(unsigned line, IUnknown *unk, IMoniker *exmon, LPCWSTR exurl) +{ + IHTMLDocument2 *doc; + IPersistMoniker *permon; + IMoniker *mon = (void*)0xdeadbeef; + BSTR doc_url = (void*)0xdeadbeef; + HRESULT hres; + + hres = IUnknown_QueryInterface(unk, &IID_IPersistMoniker, (void**)&permon); + ok(hres == S_OK, "QueryInterface(IID_IPersistMoniker) failed: %08x\n", hres); + if(FAILED(hres)) + return; + + hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&doc); + ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument2) failed: %08x\n", hres); + + hres = IHTMLDocument2_get_URL(doc, &doc_url); + ok(hres == S_OK, "get_URL failed: %08x\n", hres); + + hres = IPersistMoniker_GetCurMoniker(permon, &mon); + IPersistMoniker_Release(permon); + + if(exmon) { + LPOLESTR url; + BOOL exb = expect_GetDisplayName; + BOOL clb = called_GetDisplayName; + + ok_(__FILE__,line)(hres == S_OK, "GetCurrentMoniker failed: %08x\n", hres); + ok_(__FILE__,line)(mon == exmon, "mon(%p) != exmon(%p)\n", mon, exmon); + + if(mon == &Moniker) + SET_EXPECT(GetDisplayName); + hres = IMoniker_GetDisplayName(mon, NULL, NULL, &url); + ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres); + if(mon == &Moniker) + CHECK_CALLED(GetDisplayName); + expect_GetDisplayName = exb; + called_GetDisplayName = clb; + + ok(!lstrcmpW(url, doc_url), "url != doc_url\n"); + CoTaskMemFree(url); + }else if(exurl) { + LPOLESTR url; + + ok(hres == S_OK, "GetCurrentMoniker failed: %08x\n", hres); + + hres = IMoniker_GetDisplayName(mon, NULL, NULL, &url); + ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres); + + ok(!lstrcmpW(url, exurl), "unexpected url\n"); + ok(!lstrcmpW(url, doc_url), "url != doc_url\n"); + + CoTaskMemFree(url); + }else { + ok(hres == E_UNEXPECTED, + "GetCurrentMoniker failed: %08x, expected E_UNEXPECTED\n", hres); + ok(mon == (IMoniker*)0xdeadbeef, "mon=%p\n", mon); + ok(!lstrcmpW(doc_url, about_blank_url), "doc_url is not about:blank\n"); + } + + SysFreeString(doc_url); + IHTMLDocument_Release(doc); + if(mon && mon != (void*)0xdeadbeef) + IMoniker_Release(mon); +} + DEFINE_GUID(IID_External_unk,0x30510406,0x98B5,0x11CF,0xBB,0x82,0x00,0xAA,0x00,0xBD,0xCE,0x0B); static HRESULT WINAPI External_QueryInterface(IDispatch *iface, REFIID riid, void **ppv) @@ -672,6 +746,13 @@ static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, D test_readyState(NULL); readystate_set_interactive = (load_state != LD_INTERACTIVE); return S_OK; + case 1012: + CHECK_EXPECT(OnChanged_1012); + return S_OK; + case 3000029: + case 3000030: + /* TODO */ + return S_OK; } ok(0, "unexpected id %d\n", dispID); @@ -1204,7 +1285,12 @@ static IOleContainer OleContainer = { &OleContainerVtbl }; static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv) { - ok(0, "unexpected call\n"); + static const GUID undocumented_frame_iid = {0xfbece6c9,0x48d7,0x4a37,{0x8f,0xe3,0x6a,0xd4,0x27,0x2f,0xdd,0xac}}; + + if(!IsEqualGUID(&undocumented_frame_iid, riid)) + ok(0, "unexpected riid %s\n", debugstr_guid(riid)); + + *ppv = NULL; return E_NOINTERFACE; } @@ -1220,7 +1306,7 @@ static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface) static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd) { - ok(0, "unexpected call\n"); + CHECK_EXPECT(Frame_GetWindow); return E_NOTIMPL; } @@ -1260,7 +1346,7 @@ static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface, if(expect_InPlaceUIWindow_SetActiveObject_active) { ok(pActiveObject != NULL, "pActiveObject = NULL\n"); - if(pActiveObject && PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH) + if(pActiveObject && is_english()) ok(!lstrcmpW(wszHTML_Document, pszObjName), "pszObjName != \"HTML Document\"\n"); } else { @@ -1280,7 +1366,7 @@ static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface, if(pActiveObject) { CHECK_EXPECT2(SetActiveObject); - if(pActiveObject && PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH) + if(pActiveObject && is_english()) ok(!lstrcmpW(wszHTML_Document, pszObjName), "pszObjName != \"HTML Document\"\n"); }else { CHECK_EXPECT(SetActiveObject_null); @@ -1323,9 +1409,9 @@ static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLE static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable) { if(fEnable) - CHECK_EXPECT(Frame_EnableModeless_TRUE); + CHECK_EXPECT2(Frame_EnableModeless_TRUE); else - CHECK_EXPECT(Frame_EnableModeless_FALSE); + CHECK_EXPECT2(Frame_EnableModeless_FALSE); return E_NOTIMPL; } @@ -1386,7 +1472,7 @@ static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSiteEx *iface) static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd) { - CHECK_EXPECT(GetWindow); + CHECK_EXPECT2(GetWindow); ok(phwnd != NULL, "phwnd = NULL\n"); *phwnd = container_hwnd; return S_OK; @@ -1943,9 +2029,9 @@ static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface) static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable) { if(fEnable) - CHECK_EXPECT(EnableModeless_TRUE); + CHECK_EXPECT2(EnableModeless_TRUE); else - CHECK_EXPECT(EnableModeless_FALSE); + CHECK_EXPECT2(EnableModeless_FALSE); return E_NOTIMPL; } @@ -2168,8 +2254,12 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID return S_OK; case OLECMDID_HTTPEQUIV: CHECK_EXPECT2(Exec_HTTPEQUIV); - ok(nCmdexecopt == OLECMDEXECOPT_DONTPROMPTUSER, "nCmdexecopts=%08x\n", nCmdexecopt); - /* TODO */ + ok(!nCmdexecopt, "nCmdexecopts=%08x\n", nCmdexecopt); + ok(pvaIn != NULL, "pvaIn == NULL\n"); + ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut); + ok(V_VT(pvaIn) == VT_BSTR, "V_VT(pvaIn)=%d\n", V_VT(pvaIn)); + ok(V_BSTR(pvaIn) != NULL, "V_BSTR(pvaIn) = NULL\n"); + test_readyState(NULL); return S_OK; default: ok(0, "unexpected command %d\n", nCmdID); @@ -2187,7 +2277,7 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID if(load_from_stream) test_GetCurMoniker(doc_unk, NULL, about_blank_url); else if(!editmode) - test_GetCurMoniker(doc_unk, &Moniker, NULL); + test_GetCurMoniker(doc_unk, doc_mon, NULL); ok(pvaOut == NULL, "pvaOut=%p, expected NULL\n", pvaOut); ok(pvaIn != NULL, "pvaIn == NULL\n"); @@ -2222,6 +2312,14 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID return E_NOTIMPL; + case 140: + CHECK_EXPECT2(Exec_ShellDocView_140); + + ok(pvaIn == NULL, "pvaIn != NULL\n"); + ok(pvaOut == NULL, "pvaOut != NULL\n"); + + return E_NOTIMPL; + default: ok(0, "unexpected command %d\n", nCmdID); return E_FAIL; @@ -2267,6 +2365,9 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID ok(pvaIn == NULL, "pvaIn != NULL\n"); ok(pvaOut == NULL, "pvaOut != NULL\n"); return S_OK; + case OLECMDID_SHOWSCRIPTERROR: + /* TODO */ + return S_OK; default: ok(0, "unexpected command %d\n", nCmdID); return E_FAIL; @@ -2408,8 +2509,10 @@ static const IServiceProviderVtbl ServiceProviderVtbl = { static IServiceProvider ServiceProvider = { &ServiceProviderVtbl }; DEFINE_GUID(IID_unk1, 0xD48A6EC6,0x6A4A,0x11CF,0x94,0xA7,0x44,0x45,0x53,0x54,0x00,0x00); /* HTMLWindow2 ? */ -DEFINE_GUID(IID_unk2, 0x7BB0B520,0xB1A7,0x11D2,0xBB,0x23,0x00,0xC0,0x4F,0x79,0xAB,0xCD); -DEFINE_GUID(IID_unk3, 0x000670BA,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); +DEFINE_GUID(IID_IThumbnailView, 0x7BB0B520,0xB1A7,0x11D2,0xBB,0x23,0x00,0xC0,0x4F,0x79,0xAB,0xCD); +DEFINE_GUID(IID_IRenMailEditor, 0x000670BA,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); +DEFINE_GUID(IID_unk4, 0x305104a6,0x98b5,0x11cf,0xbb,0x82,0x00,0xaa,0x00,0xbd,0xce,0x0b); +DEFINE_GUID(IID_IDocHostUIHandlerPriv, 0xf0d241d1,0x5d0e,0x4e85,0xbc,0xb4,0xfa,0xd7,0xf7,0xc5,0x52,0x8c); static HRESULT QueryInterface(REFIID riid, void **ppv) { @@ -2441,9 +2544,13 @@ static HRESULT QueryInterface(REFIID riid, void **ppv) return E_NOINTERFACE; /* ? */ else if(IsEqualGUID(&IID_unk1, riid)) return E_NOINTERFACE; /* HTMLWindow2 ? */ - else if(IsEqualGUID(&IID_unk2, riid)) + else if(IsEqualGUID(&IID_IThumbnailView, riid)) return E_NOINTERFACE; /* ? */ - else if(IsEqualGUID(&IID_unk3, riid)) + else if(IsEqualGUID(&IID_IRenMailEditor, riid)) + return E_NOINTERFACE; /* ? */ + else if(IsEqualGUID(&IID_unk4, riid)) + return E_NOINTERFACE; /* ? */ + else if(IsEqualGUID(&IID_IDocHostUIHandlerPriv, riid)) return E_NOINTERFACE; /* ? */ else ok(0, "unexpected riid %s\n", debugstr_guid(riid)); @@ -2466,18 +2573,13 @@ static void _test_readyState(unsigned line, IUnknown *unk) VARIANT out; HRESULT hres; - static const WCHAR wszUninitialized[] = {'u','n','i','n','i','t','i','a','l','i','z','e','d',0}; - static const WCHAR wszLoading[] = {'l','o','a','d','i','n','g',0}; - static const WCHAR wszInteractive[] = {'i','n','t','e','r','a','c','t','i','v','e',0}; - static const WCHAR wszComplete[] = {'c','o','m','p','l','e','t','e',0}; - - static const LPCWSTR expected_state[] = { - wszUninitialized, - wszLoading, + static const LPCSTR expected_state[] = { + "uninitialized", + "loading", NULL, - wszInteractive, - wszComplete, - wszUninitialized + "interactive", + "complete", + "uninitialized" }; if(!unk) @@ -2493,9 +2595,13 @@ static void _test_readyState(unsigned line, IUnknown *unk) hres = IHTMLDocument2_get_readyState(htmldoc, &state); ok(hres == S_OK, "get_ReadyState failed: %08x\n", hres); + + if(!strcmp_wa(state, "interactive") && load_state == LD_LOADING) + load_state = LD_INTERACTIVE; + ok_(__FILE__, line) - (!lstrcmpW(state, expected_state[load_state]), "unexpected state \"%s\", expected %d\n", - debugstr_w(state), load_state); + (!strcmp_wa(state, expected_state[load_state]), "unexpected state %s, expected %d\n", + wine_dbgstr_w(state), load_state); SysFreeString(state); dispparams.cArgs = 0; @@ -2570,71 +2676,7 @@ static void test_ConnectionPointContainer(IUnknown *unk) IConnectionPointContainer_Release(container); } -static void test_GetCurMoniker(IUnknown *unk, IMoniker *exmon, LPCWSTR exurl) -{ - IHTMLDocument2 *doc; - IPersistMoniker *permon; - IMoniker *mon = (void*)0xdeadbeef; - BSTR doc_url = (void*)0xdeadbeef; - HRESULT hres; - - hres = IUnknown_QueryInterface(unk, &IID_IPersistMoniker, (void**)&permon); - ok(hres == S_OK, "QueryInterface(IID_IPersistMoniker) failed: %08x\n", hres); - if(FAILED(hres)) - return; - - hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&doc); - ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument2) failed: %08x\n", hres); - - hres = IHTMLDocument2_get_URL(doc, &doc_url); - ok(hres == S_OK, "get_URL failed: %08x\n", hres); - - hres = IPersistMoniker_GetCurMoniker(permon, &mon); - IPersistMoniker_Release(permon); - - if(exmon) { - LPOLESTR url; - BOOL exb = expect_GetDisplayName; - BOOL clb = called_GetDisplayName; - - ok(hres == S_OK, "GetCurrentMoniker failed: %08x\n", hres); - ok(mon == exmon, "mon(%p) != exmon(%p)\n", mon, exmon); - - SET_EXPECT(GetDisplayName); - hres = IMoniker_GetDisplayName(mon, NULL, NULL, &url); - ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres); - CHECK_CALLED(GetDisplayName); - expect_GetDisplayName = exb; - called_GetDisplayName = clb; - - ok(!lstrcmpW(url, doc_url), "url != doc_url\n"); - CoTaskMemFree(url); - }else if(exurl) { - LPOLESTR url; - - ok(hres == S_OK, "GetCurrentMoniker failed: %08x\n", hres); - - hres = IMoniker_GetDisplayName(mon, NULL, NULL, &url); - ok(hres == S_OK, "GetDisplayName failed: %08x\n", hres); - - ok(!lstrcmpW(url, exurl), "unexpected url\n"); - ok(!lstrcmpW(url, doc_url), "url != doc_url\n"); - - CoTaskMemFree(url); - }else { - ok(hres == E_UNEXPECTED, - "GetCurrentMoniker failed: %08x, expected E_UNEXPECTED\n", hres); - ok(mon == (IMoniker*)0xdeadbeef, "mon=%p\n", mon); - ok(!lstrcmpW(doc_url, about_blank_url), "doc_url is not about:blank\n"); - } - - SysFreeString(doc_url); - IHTMLDocument_Release(doc); - if(mon && mon != (void*)0xdeadbeef) - IMoniker_Release(mon); -} - -static void test_Load(IPersistMoniker *persist) +static void test_Load(IPersistMoniker *persist, IMoniker *mon) { IBindCtx *bind; HRESULT hres; @@ -2644,11 +2686,14 @@ static void test_Load(IPersistMoniker *persist) test_readyState((IUnknown*)persist); + doc_mon = mon; + CreateBindCtx(0, &bind); IBindCtx_RegisterObjectParam(bind, sz_html_clientsite_objectparam, (IUnknown*)&ClientSite); - SET_EXPECT(GetDisplayName); + if(mon == &Moniker) + SET_EXPECT(GetDisplayName); if(!set_clientsite) { SET_EXPECT(Invoke_AMBIENT_USERMODE); SET_EXPECT(GetHostInfo); @@ -2672,7 +2717,8 @@ static void test_Load(IPersistMoniker *persist) SET_EXPECT(OnChanged_READYSTATE); SET_EXPECT(Exec_ShellDocView_84); SET_EXPECT(IsSystemMoniker); - SET_EXPECT(BindToStorage); + if(mon == &Moniker) + SET_EXPECT(BindToStorage); SET_EXPECT(SetActiveObject); if(set_clientsite) { SET_EXPECT(Invoke_AMBIENT_SILENT); @@ -2683,10 +2729,11 @@ static void test_Load(IPersistMoniker *persist) expect_LockContainer_fLock = TRUE; readystate_set_loading = TRUE; - hres = IPersistMoniker_Load(persist, FALSE, &Moniker, bind, 0x12); + hres = IPersistMoniker_Load(persist, FALSE, mon, bind, 0x12); ok(hres == S_OK, "Load failed: %08x\n", hres); - CHECK_CALLED(GetDisplayName); + if(mon == &Moniker) + CHECK_CALLED(GetDisplayName); if(!set_clientsite) { CHECK_CALLED(Invoke_AMBIENT_USERMODE); CHECK_CALLED(GetHostInfo); @@ -2711,7 +2758,8 @@ static void test_Load(IPersistMoniker *persist) CHECK_CALLED(OnChanged_READYSTATE); SET_CALLED(IsSystemMoniker); /* IE7 */ SET_CALLED(Exec_ShellDocView_84); - CHECK_CALLED(BindToStorage); + if(mon == &Moniker) + CHECK_CALLED(BindToStorage); SET_CALLED(SetActiveObject); /* FIXME */ if(set_clientsite) { CHECK_CALLED(Invoke_AMBIENT_SILENT); @@ -2721,14 +2769,19 @@ static void test_Load(IPersistMoniker *persist) set_clientsite = container_locked = TRUE; - test_GetCurMoniker((IUnknown*)persist, &Moniker, NULL); + test_GetCurMoniker((IUnknown*)persist, mon, NULL); IBindCtx_Release(bind); test_readyState((IUnknown*)persist); } -static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl) +#define DWL_VERBDONE 0x0001 +#define DWL_CSS 0x0002 +#define DWL_TRYCSS 0x0004 +#define DWL_HTTP 0x0008 + +static void test_download(DWORD flags) { HWND hwnd; MSG msg; @@ -2738,17 +2791,16 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl) test_readyState(NULL); - if(verb_done) { + if(flags & (DWL_VERBDONE|DWL_HTTP)) SET_EXPECT(Exec_SETPROGRESSMAX); - if(!load_from_stream) - SET_EXPECT(GetHostInfo); - } + if((flags & DWL_VERBDONE) && !load_from_stream) + SET_EXPECT(GetHostInfo); SET_EXPECT(SetStatusText); SET_EXPECT(Exec_SETDOWNLOADSTATE_1); SET_EXPECT(GetDropTarget); - if(css_try_dwl) + if(flags & DWL_TRYCSS) SET_EXPECT(Exec_ShellDocView_84); - if(css_dwl) { + if(flags & DWL_CSS) { SET_EXPECT(CreateInstance); SET_EXPECT(Start); SET_EXPECT(LockRequest); @@ -2761,12 +2813,18 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl) SET_EXPECT(Frame_EnableModeless_TRUE); /* IE7 */ SET_EXPECT(EnableModeless_FALSE); /* IE7 */ SET_EXPECT(Frame_EnableModeless_FALSE); /* IE7 */ + if(doc_mon != &Moniker) { + SET_EXPECT(OnChanged_1012); + SET_EXPECT(Exec_HTTPEQUIV); + SET_EXPECT(Exec_SETTITLE); + } SET_EXPECT(OnChanged_1005); SET_EXPECT(OnChanged_READYSTATE); SET_EXPECT(Exec_SETPROGRESSPOS); SET_EXPECT(Exec_SETDOWNLOADSTATE_0); SET_EXPECT(Exec_ShellDocView_103); SET_EXPECT(Exec_ShellDocView_105); + SET_EXPECT(Exec_ShellDocView_140); SET_EXPECT(Exec_MSHTML_PARSECOMPLETE); SET_EXPECT(Exec_HTTPEQUIV_DONE); SET_EXPECT(SetStatusText); @@ -2777,17 +2835,18 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl) DispatchMessage(&msg); } - if(verb_done) { + if(flags & DWL_VERBDONE) CHECK_CALLED(Exec_SETPROGRESSMAX); - if(!load_from_stream) - CHECK_CALLED(GetHostInfo); - } + if(flags & DWL_HTTP) + SET_CALLED(Exec_SETPROGRESSMAX); + if((flags & DWL_VERBDONE) && !load_from_stream) + CHECK_CALLED(GetHostInfo); CHECK_CALLED(SetStatusText); CHECK_CALLED(Exec_SETDOWNLOADSTATE_1); CHECK_CALLED(GetDropTarget); - if(css_try_dwl) + if(flags & DWL_TRYCSS) SET_CALLED(Exec_ShellDocView_84); - if(css_dwl) { + if(flags & DWL_CSS) { if(called_CreateInstance) { CHECK_CALLED(CreateInstance); CHECK_CALLED(Start); @@ -2814,12 +2873,18 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl) SET_CALLED(Frame_EnableModeless_TRUE); /* IE7 */ SET_CALLED(EnableModeless_FALSE); /* IE7 */ SET_CALLED(Frame_EnableModeless_FALSE); /* IE7 */ + if(doc_mon != &Moniker) todo_wine { + CHECK_CALLED(OnChanged_1012); + CHECK_CALLED(Exec_HTTPEQUIV); + CHECK_CALLED(Exec_SETTITLE); + } CHECK_CALLED(OnChanged_1005); CHECK_CALLED(OnChanged_READYSTATE); CHECK_CALLED(Exec_SETPROGRESSPOS); CHECK_CALLED(Exec_SETDOWNLOADSTATE_0); SET_CALLED(Exec_ShellDocView_103); SET_CALLED(Exec_ShellDocView_105); + SET_CALLED(Exec_ShellDocView_140); CHECK_CALLED(Exec_MSHTML_PARSECOMPLETE); CHECK_CALLED(Exec_HTTPEQUIV_DONE); SET_CALLED(SetStatusText); @@ -2829,7 +2894,7 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl) test_readyState(NULL); } -static void test_Persist(IUnknown *unk) +static void test_Persist(IUnknown *unk, IMoniker *mon) { IPersistMoniker *persist_mon; IPersistFile *persist_file; @@ -2860,7 +2925,7 @@ static void test_Persist(IUnknown *unk) ok(IsEqualGUID(&CLSID_HTMLDocument, &guid), "guid != CLSID_HTMLDocument\n"); if(load_state == LD_DOLOAD) - test_Load(persist_mon); + test_Load(persist_mon, mon); test_readyState(unk); @@ -3173,7 +3238,7 @@ static void test_exec_fontname(IUnknown *unk, LPCWSTR name, LPCWSTR exname) if(V_VT(out) == VT_BSTR) { if(exname) ok(!lstrcmpW(V_BSTR(out), name ? name : exname), - "unexpected fontname \"%s\"\n", debugstr_w(name)); + "unexpected fontname %s\n", wine_dbgstr_w(name)); else ok(V_BSTR(out) == NULL, "V_BSTR(out) != NULL\n"); } @@ -3826,14 +3891,14 @@ static void test_HTMLDocument(BOOL do_load) test_external(unk, FALSE); test_ConnectionPointContainer(unk); test_GetCurMoniker(unk, NULL, NULL); - test_Persist(unk); + test_Persist(unk, &Moniker); if(!do_load) test_OnAmbientPropertyChange2(unk); test_Activate(unk, CLIENTSITE_EXPECTPATH); if(do_load) { - test_download(FALSE, TRUE, TRUE); + test_download(DWL_CSS|DWL_TRYCSS); test_GetCurMoniker(unk, &Moniker, NULL); } @@ -3921,14 +3986,14 @@ static void test_HTMLDocument_hlink(void) test_ConnectionPointContainer(unk); test_GetCurMoniker(unk, NULL, NULL); - test_Persist(unk); + test_Persist(unk, &Moniker); test_Navigate(unk); if(show_failed) { IUnknown_Release(unk); return; } - test_download(FALSE, TRUE, TRUE); + test_download(DWL_CSS|DWL_TRYCSS); test_IsDirty(unk, S_FALSE); test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); @@ -3948,6 +4013,62 @@ static void test_HTMLDocument_hlink(void) ok(ref == 0, "ref=%d, expected 0\n", ref); } +static void test_HTMLDocument_http(void) +{ + IMoniker *http_mon; + IUnknown *unk; + ULONG ref; + HRESULT hres; + + static const WCHAR http_urlW[] = + {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',0}; + + trace("Testing HTMLDocument (http)...\n"); + + hres = CreateURLMoniker(NULL, http_urlW, &http_mon); + ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres); + + init_test(LD_DOLOAD); + ipsex = TRUE; + + hres = create_document(&unk); + if(FAILED(hres)) + return; + doc_unk = unk; + + test_ConnectionPointContainer(unk); + test_GetCurMoniker(unk, NULL, NULL); + test_Persist(unk, http_mon); + test_Navigate(unk); + if(show_failed) { + IUnknown_Release(unk); + return; + } + + if (winetest_interactive || ! is_ie_hardened()) + test_download(DWL_HTTP); + else + win_skip("IE running in Enhanced Security Configuration\n"); + + test_IsDirty(unk, S_FALSE); + test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); + + test_InPlaceDeactivate(unk, TRUE); + test_Close(unk, FALSE); + test_IsDirty(unk, S_FALSE); + test_GetCurMoniker(unk, http_mon, NULL); + + if(view) + IOleDocumentView_Release(view); + view = NULL; + + ref = IUnknown_Release(unk); + ok(!ref, "ref=%d, expected 0\n", ref); + + ref = IMoniker_Release(http_mon); + ok(!ref, "ref=%d, expected 0\n", ref); +} + static void test_HTMLDocument_StreamLoad(void) { IOleObject *oleobj; @@ -3979,7 +4100,7 @@ static void test_HTMLDocument_StreamLoad(void) test_GetCurMoniker(unk, NULL, NULL); test_StreamLoad(unk); - test_download(TRUE, FALSE, TRUE); + test_download(DWL_VERBDONE|DWL_TRYCSS); test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); test_UIDeactivate(); @@ -4052,7 +4173,7 @@ static void test_editing_mode(BOOL do_load) test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); if(do_load) - test_Persist(unk); + test_Persist(unk, &Moniker); stream_read = protocol_read = 0; test_exec_editmode(unk, do_load); test_UIDeactivate(); @@ -4060,7 +4181,7 @@ static void test_editing_mode(BOOL do_load) IOleObject_Release(oleobj); test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED); - test_download(TRUE, do_load, do_load); + test_download(DWL_VERBDONE | (do_load ? DWL_CSS|DWL_TRYCSS : 0)); SET_EXPECT(SetStatusText); /* ignore race in native mshtml */ test_timer(EXPECT_UPDATEUI); @@ -4214,6 +4335,7 @@ START_TEST(htmldoc) test_HTMLDocument_StreamLoad(); test_editing_mode(FALSE); test_editing_mode(TRUE); + test_HTMLDocument_http(); } test_HTMLDoc_ISupportErrorInfo(); test_IPersistHistory(); diff --git a/rostests/winetests/mshtml/mshtml.rbuild b/rostests/winetests/mshtml/mshtml.rbuild index 99f208b4c8c..f844a7b52fb 100644 --- a/rostests/winetests/mshtml/mshtml.rbuild +++ b/rostests/winetests/mshtml/mshtml.rbuild @@ -5,6 +5,7 @@ . dom.c + events.c htmldoc.c misc.c protocol.c diff --git a/rostests/winetests/mshtml/mshtml_test.h b/rostests/winetests/mshtml/mshtml_test.h new file mode 100644 index 00000000000..7f2cdf2eef3 --- /dev/null +++ b/rostests/winetests/mshtml/mshtml_test.h @@ -0,0 +1,38 @@ +/* + * Copyright 2009 Ge van Geldorp for VMware, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */ +/* Note: this code is duplicated in dlls/mshtml/tests/mshtml_test.h and dlls/urlmon/tests/sec_mgr.c */ +static BOOL is_ie_hardened(void) +{ + HKEY zone_map; + DWORD ie_harden, type, size; + + ie_harden = 0; + if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap", + 0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) { + size = sizeof(DWORD); + if (RegQueryValueEx(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS || + type != REG_DWORD) { + ie_harden = 0; + } + RegCloseKey(zone_map); + } + + return ie_harden != 0; +} diff --git a/rostests/winetests/mshtml/protocol.c b/rostests/winetests/mshtml/protocol.c index 36355bf36b0..1369ff73621 100644 --- a/rostests/winetests/mshtml/protocol.c +++ b/rostests/winetests/mshtml/protocol.c @@ -20,6 +20,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" @@ -56,6 +57,7 @@ DEFINE_GUID(CLSID_ResProtocol, 0x3050F3BC, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); +DEFINE_GUID(CLSID_JSProtocol, 0x3050F3B2, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_EXPECT(GetBindInfo); DEFINE_EXPECT(ReportProgress); @@ -69,11 +71,17 @@ static DWORD bindf; static const WCHAR about_blank_url[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; static const WCHAR about_test_url[] = {'a','b','o','u','t',':','t','e','s','t',0}; static const WCHAR about_res_url[] = {'r','e','s',':','b','l','a','n','k',0}; +static const WCHAR javascript_test_url[] = {'j','a','v','a','s','c','r','i','p','t',':','t','e','s','t','(',')',0}; -static const char *debugstr_w(LPCWSTR str) +static const char *debugstr_guid(REFIID riid) { - static char buf[1024]; - WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL); + static char buf[50]; + + sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], + riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], + riid->Data4[5], riid->Data4[6], riid->Data4[7]); + return buf; } @@ -83,6 +91,9 @@ static HRESULT WINAPI ProtocolSink_QueryInterface(IInternetProtocolSink *iface, *ppv = iface; return S_OK; } + + *ppv = NULL; + ok(0, "unexpected riid %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } @@ -167,6 +178,9 @@ static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, REFIID r *ppv = iface; return S_OK; } + + *ppv = NULL; + ok(0, "unexpected riid %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } @@ -278,7 +292,7 @@ static void res_sec_url_cmp(LPCWSTR url, DWORD size, LPCWSTR file) len += sizeof(fileW)/sizeof(WCHAR)+1; ok(len == size, "wrong size %u, expected %u\n", size, len); - ok(!lstrcmpW(url + sizeof(fileW)/sizeof(WCHAR), buf), "wrong file part %s\n", debugstr_w(url)); + ok(!lstrcmpW(url + sizeof(fileW)/sizeof(WCHAR), buf), "wrong file part %s\n", wine_dbgstr_w(url)); } static void test_res_protocol(void) @@ -350,14 +364,18 @@ static void test_res_protocol(void) sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); - ok(size == sizeof(blank_url)/sizeof(WCHAR), "size=%d\n", size); + ok(size == sizeof(blank_url)/sizeof(WCHAR) || + size == sizeof(buf)/sizeof(buf[0]), /* IE8 */ + "size=%d\n", size); size = 0xdeadbeef; hres = IInternetProtocolInfo_ParseUrl(protocol_info, wrong_url1, PARSE_DOMAIN, 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); - ok(size == sizeof(wrong_url1)/sizeof(WCHAR), "size=%d\n", size); + ok(size == sizeof(wrong_url1)/sizeof(WCHAR) || + size == sizeof(buf)/sizeof(buf[0]), /* IE8 */ + "size=%d\n", size); if (0) { @@ -653,7 +671,9 @@ static void test_about_protocol(void) sizeof(buf)/sizeof(buf[0]), &size, 0); ok(hres == S_OK || hres == E_FAIL, "ParseUrl failed: %08x\n", hres); ok(buf[0] == '?', "buf changed\n"); - ok(size == sizeof(about_blank_url)/sizeof(WCHAR), "size=%d\n", size); + ok(size == sizeof(about_blank_url)/sizeof(WCHAR) || + size == sizeof(buf)/sizeof(buf[0]), /* IE8 */ + "size=%d\n", size); if (0) { @@ -774,12 +794,108 @@ static void test_about_protocol(void) IUnknown_Release(unk); } +static void test_javascript_protocol(void) +{ + IInternetProtocolInfo *protocol_info; + IUnknown *unk; + IClassFactory *factory; + HRESULT hres; + + hres = CoGetClassObject(&CLSID_JSProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); + ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres); + if(FAILED(hres)) + return; + + hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info); + ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08x\n", hres); + if(SUCCEEDED(hres)) { + WCHAR buf[128]; + DWORD size; + int i; + + for(i = PARSE_CANONICALIZE; i <= PARSE_UNESCAPE; i++) { + if(i != PARSE_SECURITY_URL && i != PARSE_DOMAIN) { + hres = IInternetProtocolInfo_ParseUrl(protocol_info, javascript_test_url, i, 0, buf, + sizeof(buf)/sizeof(buf[0]), &size, 0); + ok(hres == INET_E_DEFAULT_ACTION, + "[%d] failed: %08x, expected INET_E_DEFAULT_ACTION\n", i, hres); + } + } + + hres = IInternetProtocolInfo_ParseUrl(protocol_info, javascript_test_url, PARSE_UNESCAPE+1, 0, buf, + sizeof(buf)/sizeof(buf[0]), &size, 0); + ok(hres == INET_E_DEFAULT_ACTION, + "ParseUrl failed: %08x, expected INET_E_DEFAULT_ACTION\n", hres); + + size = 0xdeadbeef; + hres = IInternetProtocolInfo_CombineUrl(protocol_info, javascript_test_url, javascript_test_url, + 0, buf, sizeof(buf)/sizeof(buf[0]), &size, 0); + ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, "CombineUrl failed: %08x\n", hres); + ok(size == 0xdeadbeef, "size=%d\n", size); + + hres = IInternetProtocolInfo_CompareUrl(protocol_info, javascript_test_url, javascript_test_url, 0); + ok(hres == E_NOTIMPL, "CompareUrl failed: %08x\n", hres); + + for(i=0; i<30; i++) { + switch(i) { + case QUERY_USES_NETWORK: + case QUERY_IS_SECURE: + break; + default: + hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, i, 0, + buf, sizeof(buf), &size, 0); + ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, + "QueryInfo(%d) returned: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", i, hres); + } + } + + + memset(buf, '?', sizeof(buf)); + hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0, + buf, sizeof(buf), &size, 0); + ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08x\n", hres); + ok(size == sizeof(DWORD), "size=%d\n", size); + ok(!*(DWORD*)buf, "buf=%d\n", *(DWORD*)buf); + + memset(buf, '?', sizeof(buf)); + hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0, + buf, sizeof(buf), NULL, 0); + ok(hres == S_OK, "QueryInfo(QUERY_USES_NETWORK) failed: %08x\n", hres); + ok(!*(DWORD*)buf, "buf=%d\n", *(DWORD*)buf); + + hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0, + buf, 3, &size, 0); + ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08x, expected E_FAIL\n", hres); + + hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, QUERY_USES_NETWORK, 0, + NULL, sizeof(buf), &size, 0); + ok(hres == E_FAIL, "QueryInfo(QUERY_USES_NETWORK) failed: %08x, expected E_FAIL\n", hres); + + hres = IInternetProtocolInfo_QueryInfo(protocol_info, javascript_test_url, 60, 0, + NULL, sizeof(buf), &size, 0); + ok(hres == INET_E_USE_DEFAULT_PROTOCOLHANDLER, + "QueryInfo failed: %08x, expected INET_E_USE_DEFAULT_PROTOCOLHANDLER\n", hres); + + /* FIXME: test QUERY_IS_SECURE */ + + IInternetProtocolInfo_Release(protocol_info); + } + + hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory); + ok(hres == S_OK, "Could not get IClassFactory interface\n"); + if(SUCCEEDED(hres)) + IClassFactory_Release(factory); + + IUnknown_Release(unk); +} + START_TEST(protocol) { OleInitialize(NULL); test_res_protocol(); test_about_protocol(); + test_javascript_protocol(); OleUninitialize(); } diff --git a/rostests/winetests/mshtml/script.c b/rostests/winetests/mshtml/script.c index 4faf78aa9f3..5f59ea4e1b6 100644 --- a/rostests/winetests/mshtml/script.c +++ b/rostests/winetests/mshtml/script.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Jacek Caban for CodeWeavers + * Copyright 2008-2009 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,9 +33,14 @@ #include "activdbg.h" #include "objsafe.h" #include "mshtmdid.h" +#include "mshtml_test.h" DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); +/* Defined as extern in urlmon.idl, but not exported by uuid.lib */ +const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY = + {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}}; + #ifdef _WIN64 #define CTXARG_T DWORDLONG @@ -74,6 +79,12 @@ DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00 expect_ ## func = called_ ## func = FALSE; \ }while(0) +#define CHECK_CALLED_BROKEN(func) \ + do { \ + ok(called_ ## func || broken(!called_ ## func), "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + #define CHECK_NOT_CALLED(func) \ do { \ ok(!called_ ## func, "unexpected " #func "\n"); \ @@ -89,7 +100,9 @@ DEFINE_EXPECT(GetInterfaceSafetyOptions); DEFINE_EXPECT(SetInterfaceSafetyOptions); DEFINE_EXPECT(InitNew); DEFINE_EXPECT(Close); -DEFINE_EXPECT(SetProperty); +DEFINE_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK); +DEFINE_EXPECT(SetProperty_INVOKEVERSIONING); +DEFINE_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); DEFINE_EXPECT(SetScriptSite); DEFINE_EXPECT(GetScriptState); DEFINE_EXPECT(SetScriptState_STARTED); @@ -99,22 +112,26 @@ DEFINE_EXPECT(AddNamedItem); DEFINE_EXPECT(ParseScriptText); DEFINE_EXPECT(GetScriptDispatch); DEFINE_EXPECT(funcDisp); +DEFINE_EXPECT(script_testprop_d); +DEFINE_EXPECT(script_testprop_i); +DEFINE_EXPECT(AXQueryInterface_IActiveScript); +DEFINE_EXPECT(AXQueryInterface_IObjectSafety); +DEFINE_EXPECT(AXGetInterfaceSafetyOptions); +DEFINE_EXPECT(AXSetInterfaceSafetyOptions); #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}" +#define DISPID_SCRIPT_TESTPROP 0x100000 + static const GUID CLSID_TestScript = {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}}; +static const GUID CLSID_TestActiveX = + {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}}; static IHTMLDocument2 *notif_doc; static IDispatchEx *window_dispex; static BOOL doc_complete; - -static const char *debugstr_w(LPCWSTR str) -{ - static char buf[1024]; - WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL); - return buf; -} +static IDispatch *script_disp; static const char *debugstr_guid(REFIID riid) { @@ -128,6 +145,25 @@ static const char *debugstr_guid(REFIID riid) return buf; } +static int strcmp_wa(LPCWSTR strw, const char *stra) +{ + CHAR buf[512]; + WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); + return lstrcmpA(stra, buf); +} + +static BSTR a2bstr(const char *str) +{ + BSTR ret; + int len; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = SysAllocStringLen(NULL, len); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + + return ret; +} + static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, REFIID riid, void**ppv) { @@ -240,7 +276,7 @@ static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) { - ok(0, "unexpected call %s %x\n", debugstr_w(bstrName), grfdex); + ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex); return E_NOTIMPL; } @@ -324,6 +360,67 @@ static IDispatchExVtbl testObjVtbl = { static IDispatchEx funcDisp = { &testObjVtbl }; +static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) +{ + if(!strcmp_wa(bstrName, "testProp")) { + CHECK_EXPECT(script_testprop_d); + ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex); + *pid = DISPID_SCRIPT_TESTPROP; + return S_OK; + } + + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI scriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + switch(id) { + case DISPID_SCRIPT_TESTPROP: + CHECK_EXPECT(script_testprop_i); + + ok(lcid == 0, "lcid = %x\n", lcid); + ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pdp->cArgs == 0, "pdp->cArgs = %d\n", pdp->cArgs); + ok(pdp->cNamedArgs == 0, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs); + ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs != NULL\n"); + ok(!pdp->rgvarg, "rgvarg != NULL\n"); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(pei != NULL, "pei == NULL\n"); + ok(!pspCaller, "pspCaller != NULL\n"); + + V_VT(pvarRes) = VT_NULL; + break; + default: + ok(0, "unexpected call\n"); + return E_NOTIMPL; + } + + return S_OK; +} + +static IDispatchExVtbl scriptDispVtbl = { + DispatchEx_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + DispatchEx_Invoke, + scriptDisp_GetDispID, + scriptDisp_InvokeEx, + DispatchEx_DeleteMemberByName, + DispatchEx_DeleteMemberByDispID, + DispatchEx_GetMemberProperties, + DispatchEx_GetMemberName, + DispatchEx_GetNextDispID, + DispatchEx_GetNameSpaceParent +}; + +static IDispatchEx scriptDisp = { &scriptDispVtbl }; + static IHTMLDocument2 *create_document(void) { IHTMLDocument2 *doc; @@ -430,7 +527,7 @@ static SCRIPTSTATE state; static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv) { *ppv = NULL; - ok(0, "unexpected call\n"); + ok(0, "unexpected call %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } @@ -484,6 +581,110 @@ static const IObjectSafetyVtbl ObjectSafetyVtbl = { static IObjectSafety ObjectSafety = { &ObjectSafetyVtbl }; +static HRESULT WINAPI AXObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID_IActiveScript, riid)) { + CHECK_EXPECT(AXQueryInterface_IActiveScript); + return E_NOINTERFACE; + } + + if(IsEqualGUID(&IID_IObjectSafety, riid)) { + CHECK_EXPECT(AXQueryInterface_IObjectSafety); + *ppv = iface; + return S_OK; + } + + ok(0, "unexpected call %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static HRESULT WINAPI AXObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid, + DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions) +{ + CHECK_EXPECT(AXGetInterfaceSafetyOptions); + + ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid)); + ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n"); + ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n"); + + *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER; + *pdwEnabledOptions = INTERFACE_USES_DISPEX; + + return S_OK; +} + +static HRESULT WINAPI AXObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid, + DWORD dwOptionSetMask, DWORD dwEnabledOptions) +{ + CHECK_EXPECT(AXSetInterfaceSafetyOptions); + + ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid)); + + ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER), + "dwOptionSetMask=%x\n", dwOptionSetMask); + ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER), + "dwEnabledOptions=%x\n", dwOptionSetMask); + + return S_OK; +} + +static const IObjectSafetyVtbl AXObjectSafetyVtbl = { + AXObjectSafety_QueryInterface, + ObjectSafety_AddRef, + ObjectSafety_Release, + AXObjectSafety_GetInterfaceSafetyOptions, + AXObjectSafety_SetInterfaceSafetyOptions +}; + +static IObjectSafety AXObjectSafety = { &AXObjectSafetyVtbl }; + +static void test_security(void) +{ + IInternetHostSecurityManager *sec_mgr; + IServiceProvider *sp; + DWORD policy, policy_size; + struct CONFIRMSAFETY cs; + BYTE *ppolicy; + HRESULT hres; + + hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres); + + hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, + &IID_IInternetHostSecurityManager, (void**)&sec_mgr); + IServiceProvider_Release(sp); + ok(hres == S_OK, "QueryService failed: %08x\n", hres); + + hres = IInternetHostSecurityManager_ProcessUrlAction(sec_mgr, URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy), + (BYTE*)&CLSID_TestActiveX, sizeof(CLSID), 0, 0); + ok(hres == S_OK, "ProcessUrlAction failed: %08x\n", hres); + ok(policy == URLPOLICY_ALLOW, "policy = %x\n", policy); + + cs.clsid = CLSID_TestActiveX; + cs.pUnk = (IUnknown*)&AXObjectSafety; + cs.dwFlags = 0; + + SET_EXPECT(AXQueryInterface_IActiveScript); + SET_EXPECT(AXQueryInterface_IObjectSafety); + SET_EXPECT(AXGetInterfaceSafetyOptions); + SET_EXPECT(AXSetInterfaceSafetyOptions); + hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, + &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); + CHECK_CALLED(AXQueryInterface_IActiveScript); + CHECK_CALLED(AXQueryInterface_IObjectSafety); + CHECK_CALLED(AXGetInterfaceSafetyOptions); + CHECK_CALLED(AXSetInterfaceSafetyOptions); + + ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres); + ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size); + ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy); + CoTaskMemFree(ppolicy); + + IInternetHostSecurityManager_Release(sec_mgr); +} + static HRESULT WINAPI ActiveScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv) { *ppv = NULL; @@ -511,15 +712,31 @@ static HRESULT WINAPI ActiveScriptProperty_GetProperty(IActiveScriptProperty *if static HRESULT WINAPI ActiveScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty, VARIANT *pvarIndex, VARIANT *pvarValue) { - CHECK_EXPECT(SetProperty); + switch(dwProperty) { + case SCRIPTPROP_HACK_TRIDENTEVENTSINK: + CHECK_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK); + ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue)); + ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue)); + break; + case SCRIPTPROP_INVOKEVERSIONING: + CHECK_EXPECT(SetProperty_INVOKEVERSIONING); + ok(V_VT(pvarValue) == VT_I4, "V_VT(pvarValue)=%d\n", V_VT(pvarValue)); + ok(V_I4(pvarValue) == 1, "V_I4(pvarValue)=%d\n", V_I4(pvarValue)); + break; + case SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION: + CHECK_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); + ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue)); + ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue)); + break; + default: + ok(0, "unexpected property %x\n", dwProperty); + return E_NOTIMPL; + } - ok(dwProperty == SCRIPTPROP_HACK_TRIDENTEVENTSINK, "unexpected property %d\n", dwProperty); ok(!pvarIndex, "pvarIndex != NULL\n"); ok(pvarValue != NULL, "pvarValue == NULL\n"); - ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue)); - ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue)); - return E_NOTIMPL; + return S_OK; } static const IActiveScriptPropertyVtbl ActiveScriptPropertyVtbl = { @@ -600,17 +817,117 @@ static HRESULT WINAPI ActiveScriptParse_AddScriptlet(IActiveScriptParse *iface, return E_NOTIMPL; } +static HRESULT dispex_propput(IDispatchEx *obj, DISPID id, VARIANT *var) +{ + DISPID propput_arg = DISPID_PROPERTYPUT; + DISPPARAMS dp = {var, &propput_arg, 1, 1}; + EXCEPINFO ei = {0}; + + return IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL); +} + +static void test_func(IDispatchEx *obj) +{ + DISPID id; + IDispatchEx *dispex; + IDispatch *disp; + EXCEPINFO ei; + DISPPARAMS dp; + BSTR str; + VARIANT var; + HRESULT hres; + + str = a2bstr("toString"); + hres = IDispatchEx_GetDispID(obj, str, fdexNameCaseSensitive, &id); + SysFreeString(str); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + ok(id == DISPID_IOMNAVIGATOR_TOSTRING, "id = %x\n", id); + + memset(&dp, 0, sizeof(dp)); + memset(&ei, 0, sizeof(ei)); + VariantInit(&var); + hres = IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var)); + ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n"); + disp = V_DISPATCH(&var); + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + IDispatch_Release(disp); + ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres); + + /* FIXME: Test InvokeEx(DISPATCH_METHOD) */ + + memset(&dp, 0, sizeof(dp)); + memset(&ei, 0, sizeof(ei)); + VariantInit(&var); + hres = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &var, &ei, NULL); + ok(hres == S_OK || broken(E_ACCESSDENIED), "InvokeEx failed: %08x\n", hres); + if(SUCCEEDED(hres)) { + ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var)); + ok(!strcmp_wa(V_BSTR(&var), "[object]"), "V_BSTR(var) = %s\n", wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); + } + + V_VT(&var) = VT_I4; + V_I4(&var) = 100; + hres = dispex_propput(obj, id, &var); + ok(hres == E_NOTIMPL, "InvokeEx failed: %08x\n", hres); + + IDispatchEx_Release(dispex); +} + +static void test_nextdispid(IDispatchEx *dispex) +{ + DISPID last_id = DISPID_STARTENUM, id, dyn_id; + BSTR name; + VARIANT var; + HRESULT hres; + + name = a2bstr("dynVal"); + hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseSensitive|fdexNameEnsure, &dyn_id); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + SysFreeString(name); + + V_VT(&var) = VT_EMPTY; + hres = dispex_propput(dispex, dyn_id, &var); + + while(last_id != dyn_id) { + hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, last_id, &id); + ok(hres == S_OK, "GetNextDispID returned: %08x\n", hres); + ok(id != DISPID_STARTENUM, "id == DISPID_STARTENUM\n"); + ok(id != DISPID_IOMNAVIGATOR_TOSTRING, "id == DISPID_IOMNAVIGATOR_TOSTRING\n"); + + hres = IDispatchEx_GetMemberName(dispex, id, &name); + ok(hres == S_OK, "GetMemberName failed: %08x\n", hres); + + if(id == dyn_id) + ok(!strcmp_wa(name, "dynVal"), "name = %s\n", wine_dbgstr_w(name)); + else if(id == DISPID_IOMNAVIGATOR_PLATFORM) + ok(!strcmp_wa(name, "platform"), "name = %s\n", wine_dbgstr_w(name)); + + SysFreeString(name); + last_id = id; + } + + hres = IDispatchEx_GetNextDispID(dispex, 0, id, &id); + ok(hres == S_FALSE, "GetNextDispID returned: %08x\n", hres); + ok(id == DISPID_STARTENUM, "id != DISPID_STARTENUM\n"); +} + static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface, LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine, DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo) { - IDispatchEx *document; + IDispatchEx *document, *dispex; + IHTMLWindow2 *window; + IOmNavigator *navigator; IUnknown *unk; VARIANT var, arg; DISPPARAMS dp; EXCEPINFO ei; - DISPID id, named_arg = DISPID_PROPERTYPUT; + DISPID id; BSTR tmp; HRESULT hres; @@ -628,7 +945,7 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres); ok(id == DISPID_IHTMLWINDOW2_DOCUMENT, "id=%x\n", id); - todo_wine CHECK_CALLED(GetScriptDispatch); + CHECK_CALLED(GetScriptDispatch); VariantInit(&var); memset(&dp, 0, sizeof(dp)); @@ -657,14 +974,9 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres); ok(id, "id == 0\n"); - dp.cArgs = 1; - dp.rgvarg = &var; - dp.cNamedArgs = 1; - dp.rgdispidNamedArgs = &named_arg; V_VT(&var) = VT_I4; V_I4(&var) = 100; - - hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL); + hres = dispex_propput(document, id, &var); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); tmp = SysAllocString(testW); @@ -698,7 +1010,6 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac dp.rgdispidNamedArgs = NULL; V_VT(&var) = VT_DISPATCH; V_DISPATCH(&var) = (IDispatch*)&funcDisp; - hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL); ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); @@ -720,6 +1031,51 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac IDispatchEx_Release(document); + hres = IDispatchEx_QueryInterface(window_dispex, &IID_IHTMLWindow2, (void**)&window); + ok(hres == S_OK, "Could not get IHTMLWindow2 iface: %08x\n", hres); + + hres = IHTMLWindow2_get_navigator(window, &navigator); + IHTMLWindow2_Release(window); + ok(hres == S_OK, "get_navigator failed: %08x\n", hres); + + hres = IOmNavigator_QueryInterface(navigator, &IID_IDispatchEx, (void**)&dispex); + IOmNavigator_Release(navigator); + ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres); + + test_func(dispex); + test_nextdispid(dispex); + IDispatchEx_Release(dispex); + + script_disp = (IDispatch*)&scriptDisp; + + SET_EXPECT(GetScriptDispatch); + SET_EXPECT(script_testprop_d); + tmp = a2bstr("testProp"); + hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n"); + CHECK_CALLED(GetScriptDispatch); + CHECK_CALLED(script_testprop_d); + SysFreeString(tmp); + + tmp = a2bstr("testProp"); + hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id); + ok(hres == S_OK, "GetDispID failed: %08x\n", hres); + ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n"); + SysFreeString(tmp); + + SET_EXPECT(GetScriptDispatch); + SET_EXPECT(script_testprop_i); + memset(&ei, 0, sizeof(ei)); + memset(&dp, 0, sizeof(dp)); + hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL); + ok(hres == S_OK, "InvokeEx failed: %08x\n", hres); + ok(V_VT(&var) == VT_NULL, "V_VT(var) = %d\n", V_VT(&var)); + CHECK_CALLED(GetScriptDispatch); + CHECK_CALLED(script_testprop_i); + + test_security(); + return S_OK; } @@ -763,6 +1119,9 @@ static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID r return S_OK; } + if(IsEqualGUID(&IID_IActiveScriptDebug, riid)) + return E_NOINTERFACE; + ok(0, "unexpected riid %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } @@ -810,7 +1169,7 @@ static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveSc ok(hres == E_NOINTERFACE, "Could not get IID_ICanHandleException interface: %08x\n", hres); hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service); - todo_wine ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres); + ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres); if(SUCCEEDED(hres)) IServiceProvider_Release(service); @@ -876,7 +1235,7 @@ static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface, CHECK_EXPECT(AddNamedItem); - ok(!lstrcmpW(pstrName, windowW), "pstrName=%s\n", debugstr_w(pstrName)); + ok(!lstrcmpW(pstrName, windowW), "pstrName=%s\n", wine_dbgstr_w(pstrName)); ok(dwFlags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS), "dwFlags=%x\n", dwFlags); hres = IActiveScriptSite_GetItemInfo(site, windowW, SCRIPTINFO_IUNKNOWN, &unk, NULL); @@ -911,7 +1270,14 @@ static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOL IDispatch **ppdisp) { CHECK_EXPECT(GetScriptDispatch); - return E_NOTIMPL; + + ok(!strcmp_wa(pstrItemName, "window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName)); + + if(!script_disp) + return E_NOTIMPL; + + *ppdisp = script_disp; + return S_OK; } static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface, @@ -1035,12 +1401,14 @@ static void test_simple_script(void) SET_EXPECT(CreateInstance); SET_EXPECT(GetInterfaceSafetyOptions); SET_EXPECT(SetInterfaceSafetyOptions); - SET_EXPECT(SetProperty); + SET_EXPECT(SetProperty_INVOKEVERSIONING); /* IE8 */ + 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); /* IE8 */ SET_EXPECT(ParseScriptText); SET_EXPECT(SetScriptState_CONNECTED); @@ -1050,12 +1418,14 @@ static void test_simple_script(void) CHECK_CALLED(CreateInstance); CHECK_CALLED(GetInterfaceSafetyOptions); CHECK_CALLED(SetInterfaceSafetyOptions); - CHECK_CALLED(SetProperty); + CHECK_CALLED_BROKEN(SetProperty_INVOKEVERSIONING); /* IE8 */ + CHECK_CALLED(SetProperty_HACK_TRIDENTEVENTSINK); CHECK_CALLED(InitNew); CHECK_CALLED(SetScriptSite); CHECK_CALLED(GetScriptState); CHECK_CALLED(SetScriptState_STARTED); CHECK_CALLED(AddNamedItem); + CHECK_CALLED_BROKEN(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */ CHECK_CALLED(ParseScriptText); CHECK_CALLED(SetScriptState_CONNECTED); @@ -1151,27 +1521,6 @@ static void gecko_installer_workaround(BOOL disable) RegCloseKey(hkey); } -/* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */ -/* Note: this code is duplicated in dlls/mshtml/tests/dom.c, dlls/mshtml/tests/script.c and dlls/urlmon/tests/misc.c */ -static BOOL is_ie_hardened(void) -{ - HKEY zone_map; - DWORD ie_harden, type, size; - - ie_harden = 0; - if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap", - 0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) { - size = sizeof(DWORD); - if (RegQueryValueEx(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS || - type != REG_DWORD) { - ie_harden = 0; - } - RegCloseKey(zone_map); - } - - return ie_harden != 0; -} - START_TEST(script) { gecko_installer_workaround(TRUE); diff --git a/rostests/winetests/mshtml/testlist.c b/rostests/winetests/mshtml/testlist.c index 6039fe93ed2..f9026995b25 100644 --- a/rostests/winetests/mshtml/testlist.c +++ b/rostests/winetests/mshtml/testlist.c @@ -7,6 +7,7 @@ #include "wine/test.h" extern void func_dom(void); +extern void func_events(void); extern void func_htmldoc(void); extern void func_misc(void); extern void func_protocol(void); @@ -15,7 +16,8 @@ extern void func_script(void); const struct test winetest_testlist[] = { { "dom", func_dom }, - { "htmldoc", func_htmldoc }, + { "events", func_events }, + { "htmldoc", func_htmldoc }, { "misc", func_misc }, { "protocol", func_protocol }, { "script", func_script },