mshtml: Added execScript tests.
[wine] / dlls / mshtml / tests / script.c
1 /*
2  * Copyright 2008-2009 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "wininet.h"
30 #include "docobj.h"
31 #include "dispex.h"
32 #include "hlink.h"
33 #include "mshtml.h"
34 #include "mshtmhst.h"
35 #include "initguid.h"
36 #include "activscp.h"
37 #include "activdbg.h"
38 #include "objsafe.h"
39 #include "mshtmdid.h"
40 #include "mshtml_test.h"
41
42 DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
43
44 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
45 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
46     {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
47
48 #ifdef _WIN64
49
50 #define CTXARG_T DWORDLONG
51 #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
52 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl
53
54 #else
55
56 #define CTXARG_T DWORD
57 #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
58 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl
59
60 #endif
61
62 #define DEFINE_EXPECT(func) \
63     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
64
65 #define SET_EXPECT(func) \
66     do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
67
68 #define CHECK_EXPECT2(func) \
69     do { \
70         ok(expect_ ##func, "unexpected call " #func "\n"); \
71         called_ ## func = TRUE; \
72     }while(0)
73
74 #define CHECK_EXPECT(func) \
75     do { \
76         CHECK_EXPECT2(func); \
77         expect_ ## func = FALSE; \
78     }while(0)
79
80 #define CHECK_CALLED(func) \
81     do { \
82         ok(called_ ## func, "expected " #func "\n"); \
83         expect_ ## func = called_ ## func = FALSE; \
84     }while(0)
85
86 #define CHECK_CALLED_BROKEN(func) \
87     do { \
88         ok(called_ ## func || broken(!called_ ## func), "expected " #func "\n"); \
89         expect_ ## func = called_ ## func = FALSE; \
90     }while(0)
91
92 #define CHECK_NOT_CALLED(func) \
93     do { \
94         ok(!called_ ## func, "unexpected " #func "\n"); \
95         expect_ ## func = called_ ## func = FALSE; \
96     }while(0)
97
98 #define CLEAR_CALLED(func) \
99     expect_ ## func = called_ ## func = FALSE
100
101
102 DEFINE_EXPECT(CreateInstance);
103 DEFINE_EXPECT(GetInterfaceSafetyOptions);
104 DEFINE_EXPECT(SetInterfaceSafetyOptions);
105 DEFINE_EXPECT(InitNew);
106 DEFINE_EXPECT(Close);
107 DEFINE_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
108 DEFINE_EXPECT(SetProperty_INVOKEVERSIONING);
109 DEFINE_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION);
110 DEFINE_EXPECT(SetScriptSite);
111 DEFINE_EXPECT(GetScriptState);
112 DEFINE_EXPECT(SetScriptState_STARTED);
113 DEFINE_EXPECT(SetScriptState_CONNECTED);
114 DEFINE_EXPECT(SetScriptState_DISCONNECTED);
115 DEFINE_EXPECT(AddNamedItem);
116 DEFINE_EXPECT(ParseScriptText_script);
117 DEFINE_EXPECT(ParseScriptText_execScript);
118 DEFINE_EXPECT(GetScriptDispatch);
119 DEFINE_EXPECT(funcDisp);
120 DEFINE_EXPECT(script_divid_d);
121 DEFINE_EXPECT(script_testprop_d);
122 DEFINE_EXPECT(script_testprop_i);
123 DEFINE_EXPECT(script_testprop2_d);
124 DEFINE_EXPECT(AXQueryInterface_IActiveScript);
125 DEFINE_EXPECT(AXQueryInterface_IObjectSafety);
126 DEFINE_EXPECT(AXGetInterfaceSafetyOptions);
127 DEFINE_EXPECT(AXSetInterfaceSafetyOptions_IDispatch);
128 DEFINE_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx);
129 DEFINE_EXPECT(external_success);
130
131 #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
132 #define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80646}"
133
134 #define DISPID_SCRIPT_TESTPROP   0x100000
135 #define DISPID_SCRIPT_TESTPROP2  0x100001
136
137 #define DISPID_EXTERNAL_OK             0x300000
138 #define DISPID_EXTERNAL_TRACE          0x300001
139 #define DISPID_EXTERNAL_REPORTSUCCESS  0x300002
140
141 static const GUID CLSID_TestScript =
142     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
143 static const GUID CLSID_TestActiveX =
144     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
145
146 static IHTMLDocument2 *notif_doc;
147 static IOleDocumentView *view;
148 static IDispatchEx *window_dispex;
149 static BOOL doc_complete;
150 static IDispatch *script_disp;
151 static BOOL ax_objsafe;
152 static HWND container_hwnd;
153 static HRESULT ax_getopt_hres = S_OK, ax_setopt_dispex_hres = S_OK, ax_setopt_disp_hres = S_OK;
154 static DWORD ax_setopt;
155
156 static const char *debugstr_guid(REFIID riid)
157 {
158     static char buf[50];
159
160     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
161             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
162             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
163             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
164
165     return buf;
166 }
167
168 static int strcmp_wa(LPCWSTR strw, const char *stra)
169 {
170     CHAR buf[512];
171     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
172     return lstrcmpA(stra, buf);
173 }
174
175 static BSTR a2bstr(const char *str)
176 {
177     BSTR ret;
178     int len;
179
180     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
181     ret = SysAllocStringLen(NULL, len);
182     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
183
184     return ret;
185 }
186
187 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
188 {
189     HKEY hkey;
190     DWORD res;
191
192     if(!init) {
193         RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
194         return TRUE;
195     }
196
197     res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
198     if(res != ERROR_SUCCESS)
199         return FALSE;
200
201     if(def_value)
202         res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
203
204     RegCloseKey(hkey);
205
206     return res == ERROR_SUCCESS;
207 }
208
209 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
210         REFIID riid, void**ppv)
211 {
212     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
213         *ppv = iface;
214         return S_OK;
215     }
216
217     return E_NOINTERFACE;
218 }
219
220 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
221 {
222     return 2;
223 }
224
225 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
226 {
227     return 1;
228 }
229
230 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
231 {
232     if(dispID == DISPID_READYSTATE){
233         BSTR state;
234         HRESULT hres;
235
236         static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0};
237
238         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
239         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
240
241         if(!lstrcmpW(state, completeW))
242             doc_complete = TRUE;
243
244         SysFreeString(state);
245     }
246
247     return S_OK;
248 }
249
250 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
251 {
252     ok(0, "unexpected call\n");
253     return E_NOTIMPL;
254 }
255
256 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
257     PropertyNotifySink_QueryInterface,
258     PropertyNotifySink_AddRef,
259     PropertyNotifySink_Release,
260     PropertyNotifySink_OnChanged,
261     PropertyNotifySink_OnRequestEdit
262 };
263
264 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
265
266 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
267 {
268     *ppv = NULL;
269
270     if(IsEqualGUID(riid, &IID_IUnknown)
271        || IsEqualGUID(riid, &IID_IDispatch)
272        || IsEqualGUID(riid, &IID_IDispatchEx))
273         *ppv = iface;
274     else
275         return E_NOINTERFACE;
276
277     return S_OK;
278 }
279
280 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
281 {
282     return 2;
283 }
284
285 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
286 {
287     return 1;
288 }
289
290 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
291 {
292     ok(0, "unexpected call\n");
293     return E_NOTIMPL;
294 }
295
296 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
297                                               LCID lcid, ITypeInfo **ppTInfo)
298 {
299     ok(0, "unexpected call\n");
300     return E_NOTIMPL;
301 }
302
303 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
304                                                 LPOLESTR *rgszNames, UINT cNames,
305                                                 LCID lcid, DISPID *rgDispId)
306 {
307     ok(0, "unexpected call\n");
308     return E_NOTIMPL;
309 }
310
311 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
312                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
313                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
314 {
315     ok(0, "unexpected call\n");
316     return E_NOTIMPL;
317 }
318
319 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
320 {
321     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
322     return E_NOTIMPL;
323 }
324
325 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
326 {
327     ok(0, "unexpected call\n");
328     return E_NOTIMPL;
329 }
330
331 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
332 {
333     ok(0, "unexpected call\n");
334     return E_NOTIMPL;
335 }
336
337 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
338 {
339     ok(0, "unexpected call\n");
340     return E_NOTIMPL;
341 }
342
343 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
344 {
345     ok(0, "unexpected call\n");
346     return E_NOTIMPL;
347 }
348
349 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
350 {
351     ok(0, "unexpected call\n");
352     return E_NOTIMPL;
353 }
354
355 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
356 {
357     ok(0, "unexpected call\n");
358     return E_NOTIMPL;
359 }
360
361 static HRESULT WINAPI funcDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
362         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
363 {
364     CHECK_EXPECT(funcDisp);
365
366     ok(id == DISPID_VALUE, "id = %d\n", id);
367     ok(lcid == 0, "lcid = %x\n", lcid);
368     ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
369     ok(pdp != NULL, "pdp == NULL\n");
370     ok(pdp->cArgs == 2, "pdp->cArgs = %d\n", pdp->cArgs);
371     ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
372     ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
373     ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
374     ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(rgvarg[1]) = %d\n", V_VT(pdp->rgvarg));
375     ok(V_BOOL(pdp->rgvarg+1) == VARIANT_TRUE, "V_BOOL(rgvarg[1]) = %x\n", V_BOOL(pdp->rgvarg));
376     ok(pvarRes != NULL, "pvarRes == NULL\n");
377     ok(pei != NULL, "pei == NULL\n");
378     ok(!pspCaller, "pspCaller != NULL\n");
379
380     V_VT(pvarRes) = VT_I4;
381     V_I4(pvarRes) = 100;
382     return S_OK;
383 }
384
385 static IDispatchExVtbl testObjVtbl = {
386     DispatchEx_QueryInterface,
387     DispatchEx_AddRef,
388     DispatchEx_Release,
389     DispatchEx_GetTypeInfoCount,
390     DispatchEx_GetTypeInfo,
391     DispatchEx_GetIDsOfNames,
392     DispatchEx_Invoke,
393     DispatchEx_GetDispID,
394     funcDisp_InvokeEx,
395     DispatchEx_DeleteMemberByName,
396     DispatchEx_DeleteMemberByDispID,
397     DispatchEx_GetMemberProperties,
398     DispatchEx_GetMemberName,
399     DispatchEx_GetNextDispID,
400     DispatchEx_GetNameSpaceParent
401 };
402
403 static IDispatchEx funcDisp = { &testObjVtbl };
404
405 static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
406 {
407     if(!strcmp_wa(bstrName, "testProp")) {
408         CHECK_EXPECT(script_testprop_d);
409         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
410         *pid = DISPID_SCRIPT_TESTPROP;
411         return S_OK;
412     }
413
414     if(!strcmp_wa(bstrName, "testProp2")) {
415         CHECK_EXPECT(script_testprop2_d);
416         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
417         *pid = DISPID_SCRIPT_TESTPROP2;
418         return S_OK;
419     }
420
421     if(!strcmp_wa(bstrName, "divid")) {
422         CHECK_EXPECT(script_divid_d);
423         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
424         return E_FAIL;
425     }
426
427     ok(0, "unexpected call %s\n", wine_dbgstr_w(bstrName));
428     return E_NOTIMPL;
429 }
430
431 static HRESULT WINAPI scriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
432         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
433 {
434     switch(id) {
435     case DISPID_SCRIPT_TESTPROP:
436         CHECK_EXPECT(script_testprop_i);
437
438         ok(lcid == 0, "lcid = %x\n", lcid);
439         ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
440         ok(pdp != NULL, "pdp == NULL\n");
441         ok(pdp->cArgs == 0, "pdp->cArgs = %d\n", pdp->cArgs);
442         ok(pdp->cNamedArgs == 0, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
443         ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs != NULL\n");
444         ok(!pdp->rgvarg, "rgvarg != NULL\n");
445         ok(pvarRes != NULL, "pvarRes == NULL\n");
446         ok(pei != NULL, "pei == NULL\n");
447         ok(!pspCaller, "pspCaller != NULL\n");
448
449         V_VT(pvarRes) = VT_NULL;
450         break;
451     default:
452         ok(0, "unexpected call\n");
453         return E_NOTIMPL;
454     }
455
456     return S_OK;
457 }
458
459 static IDispatchExVtbl scriptDispVtbl = {
460     DispatchEx_QueryInterface,
461     DispatchEx_AddRef,
462     DispatchEx_Release,
463     DispatchEx_GetTypeInfoCount,
464     DispatchEx_GetTypeInfo,
465     DispatchEx_GetIDsOfNames,
466     DispatchEx_Invoke,
467     scriptDisp_GetDispID,
468     scriptDisp_InvokeEx,
469     DispatchEx_DeleteMemberByName,
470     DispatchEx_DeleteMemberByDispID,
471     DispatchEx_GetMemberProperties,
472     DispatchEx_GetMemberName,
473     DispatchEx_GetNextDispID,
474     DispatchEx_GetNameSpaceParent
475 };
476
477 static IDispatchEx scriptDisp = { &scriptDispVtbl };
478
479 static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
480 {
481     if(!strcmp_wa(bstrName, "ok")) {
482         *pid = DISPID_EXTERNAL_OK;
483         return S_OK;
484     }
485     if(!strcmp_wa(bstrName, "trace")) {
486         *pid = DISPID_EXTERNAL_TRACE;
487         return S_OK;
488     }
489     if(!strcmp_wa(bstrName, "reportSuccess")) {
490         *pid = DISPID_EXTERNAL_REPORTSUCCESS;
491         return S_OK;
492     }
493
494     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
495     return DISP_E_UNKNOWNNAME;
496 }
497
498 static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
499         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
500 {
501     switch(id) {
502     case DISPID_EXTERNAL_OK:
503         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
504         ok(pdp != NULL, "pdp == NULL\n");
505         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
506         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
507         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
508         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
509         ok(pei != NULL, "pei == NULL\n");
510
511         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
512         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
513         ok(V_BOOL(pdp->rgvarg+1), "%s\n", wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
514
515         return S_OK;
516
517      case DISPID_EXTERNAL_TRACE:
518         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
519         ok(pdp != NULL, "pdp == NULL\n");
520         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
521         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
522         ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
523         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
524         ok(!pvarRes, "pvarRes != NULL\n");
525         ok(pei != NULL, "pei == NULL\n");
526
527         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
528         if(V_VT(pdp->rgvarg) == VT_BSTR)
529             trace("%s\n", wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
530
531         return S_OK;
532
533     case DISPID_EXTERNAL_REPORTSUCCESS:
534         CHECK_EXPECT(external_success);
535
536         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
537         ok(pdp != NULL, "pdp == NULL\n");
538         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
539         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
540         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
541         ok(!pvarRes, "pvarRes != NULL\n");
542         ok(pei != NULL, "pei == NULL\n");
543
544         return S_OK;
545
546     default:
547         ok(0, "unexpected call\n");
548         return E_NOTIMPL;
549     }
550
551     return S_OK;
552 }
553
554 static IDispatchExVtbl externalDispVtbl = {
555     DispatchEx_QueryInterface,
556     DispatchEx_AddRef,
557     DispatchEx_Release,
558     DispatchEx_GetTypeInfoCount,
559     DispatchEx_GetTypeInfo,
560     DispatchEx_GetIDsOfNames,
561     DispatchEx_Invoke,
562     externalDisp_GetDispID,
563     externalDisp_InvokeEx,
564     DispatchEx_DeleteMemberByName,
565     DispatchEx_DeleteMemberByDispID,
566     DispatchEx_GetMemberProperties,
567     DispatchEx_GetMemberName,
568     DispatchEx_GetNextDispID,
569     DispatchEx_GetNameSpaceParent
570 };
571
572 static IDispatchEx externalDisp = { &externalDispVtbl };
573
574 static HRESULT QueryInterface(REFIID,void**);
575
576 static HRESULT WINAPI DocHostUIHandler_QueryInterface(IDocHostUIHandler2 *iface, REFIID riid, void **ppv)
577 {
578     return QueryInterface(riid, ppv);
579 }
580
581 static ULONG WINAPI DocHostUIHandler_AddRef(IDocHostUIHandler2 *iface)
582 {
583     return 2;
584 }
585
586 static ULONG WINAPI DocHostUIHandler_Release(IDocHostUIHandler2 *iface)
587 {
588     return 1;
589 }
590
591 static HRESULT WINAPI DocHostUIHandler_ShowContextMenu(IDocHostUIHandler2 *iface, DWORD dwID, POINT *ppt,
592         IUnknown *pcmdtReserved, IDispatch *pdicpReserved)
593 {
594     return E_NOTIMPL;
595 }
596
597 static HRESULT WINAPI DocHostUIHandler_GetHostInfo(IDocHostUIHandler2 *iface, DOCHOSTUIINFO *pInfo)
598 {
599     return E_NOTIMPL;
600 }
601
602 static HRESULT WINAPI DocHostUIHandler_ShowUI(IDocHostUIHandler2 *iface, DWORD dwID,
603         IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
604         IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
605 {
606     return S_OK;
607 }
608
609 static HRESULT WINAPI DocHostUIHandler_HideUI(IDocHostUIHandler2 *iface)
610 {
611     return S_OK;
612 }
613
614 static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface)
615 {
616     return S_OK;
617 }
618
619 static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable)
620 {
621     return E_NOTIMPL;
622 }
623
624 static HRESULT WINAPI DocHostUIHandler_OnDocWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
625 {
626     return E_NOTIMPL;
627 }
628
629 static HRESULT WINAPI DocHostUIHandler_OnFrameWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
630 {
631     return S_OK;
632 }
633
634 static HRESULT WINAPI DocHostUIHandler_ResizeBorder(IDocHostUIHandler2 *iface, LPCRECT prcBorder,
635         IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
636 {
637     return E_NOTIMPL;
638 }
639
640 static HRESULT WINAPI DocHostUIHandler_TranslateAccelerator(IDocHostUIHandler2 *iface, LPMSG lpMsg,
641         const GUID *pguidCmdGroup, DWORD nCmdID)
642 {
643     return E_NOTIMPL;
644 }
645
646 static HRESULT WINAPI DocHostUIHandler_GetOptionKeyPath(IDocHostUIHandler2 *iface,
647         LPOLESTR *pchKey, DWORD dw)
648 {
649     return S_OK;
650 }
651
652 static HRESULT WINAPI DocHostUIHandler_GetDropTarget(IDocHostUIHandler2 *iface,
653         IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
654 {
655     return E_NOTIMPL;
656 }
657
658 static HRESULT WINAPI DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, IDispatch **ppDispatch)
659 {
660     *ppDispatch = (IDispatch*)&externalDisp;
661     return S_OK;
662 }
663
664 static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate,
665         OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
666 {
667     return S_FALSE;
668 }
669
670 static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO,
671         IDataObject **ppPORet)
672 {
673     return E_NOTIMPL;
674 }
675
676 static HRESULT WINAPI DocHostUIHandler_GetOverrideKeyPath(IDocHostUIHandler2 *iface,
677         LPOLESTR *pchKey, DWORD dw)
678 {
679     return E_NOTIMPL;
680 }
681
682 static const IDocHostUIHandler2Vtbl DocHostUIHandlerVtbl = {
683     DocHostUIHandler_QueryInterface,
684     DocHostUIHandler_AddRef,
685     DocHostUIHandler_Release,
686     DocHostUIHandler_ShowContextMenu,
687     DocHostUIHandler_GetHostInfo,
688     DocHostUIHandler_ShowUI,
689     DocHostUIHandler_HideUI,
690     DocHostUIHandler_UpdateUI,
691     DocHostUIHandler_EnableModeless,
692     DocHostUIHandler_OnDocWindowActivate,
693     DocHostUIHandler_OnFrameWindowActivate,
694     DocHostUIHandler_ResizeBorder,
695     DocHostUIHandler_TranslateAccelerator,
696     DocHostUIHandler_GetOptionKeyPath,
697     DocHostUIHandler_GetDropTarget,
698     DocHostUIHandler_GetExternal,
699     DocHostUIHandler_TranslateUrl,
700     DocHostUIHandler_FilterDataObject,
701     DocHostUIHandler_GetOverrideKeyPath
702 };
703
704 static IDocHostUIHandler2 DocHostUIHandler = { &DocHostUIHandlerVtbl };
705
706 static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
707 {
708     return E_NOINTERFACE;
709 }
710
711 static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
712 {
713     return 2;
714 }
715
716 static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
717 {
718     return 1;
719 }
720
721 static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
722 {
723     return E_NOTIMPL;
724 }
725
726 static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
727 {
728     return E_NOTIMPL;
729 }
730
731 static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
732 {
733     return E_NOTIMPL;
734 }
735
736 static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
737         LPCBORDERWIDTHS pborderwidths)
738 {
739     return E_NOTIMPL;
740 }
741
742 static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
743         LPCBORDERWIDTHS pborderwidths)
744 {
745     return S_OK;
746 }
747
748 static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
749         IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
750 {
751     return S_OK;
752 }
753
754 static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
755         LPOLEMENUGROUPWIDTHS lpMenuWidths)
756 {
757     return E_NOTIMPL;
758 }
759
760 static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
761         HOLEMENU holemenu, HWND hwndActiveObject)
762 {
763     ok(0, "unexpected call\n");
764     return E_NOTIMPL;
765 }
766
767 static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
768 {
769     ok(0, "unexpected call\n");
770     return E_NOTIMPL;
771 }
772
773 static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
774 {
775     return S_OK;
776 }
777
778 static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
779 {
780     return E_NOTIMPL;
781 }
782
783 static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
784 {
785     ok(0, "unexpected call\n");
786     return E_NOTIMPL;
787 }
788
789 static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
790     InPlaceFrame_QueryInterface,
791     InPlaceFrame_AddRef,
792     InPlaceFrame_Release,
793     InPlaceFrame_GetWindow,
794     InPlaceFrame_ContextSensitiveHelp,
795     InPlaceFrame_GetBorder,
796     InPlaceFrame_RequestBorderSpace,
797     InPlaceFrame_SetBorderSpace,
798     InPlaceFrame_SetActiveObject,
799     InPlaceFrame_InsertMenus,
800     InPlaceFrame_SetMenu,
801     InPlaceFrame_RemoveMenus,
802     InPlaceFrame_SetStatusText,
803     InPlaceFrame_EnableModeless,
804     InPlaceFrame_TranslateAccelerator
805 };
806
807 static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
808
809 static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
810 {
811     return QueryInterface(riid, ppv);
812 }
813
814 static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
815 {
816     return 2;
817 }
818
819 static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
820 {
821     return 1;
822 }
823
824 static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
825 {
826     *phwnd = container_hwnd;
827     return S_OK;
828 }
829
830 static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
831 {
832     ok(0, "unexpected call\n");
833     return E_NOTIMPL;
834 }
835
836 static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
837 {
838     return S_OK;
839 }
840
841 static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
842 {
843     return S_OK;
844 }
845
846 static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
847 {
848     return S_OK;
849 }
850
851 static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
852         IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
853         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
854 {
855     static const RECT rect = {0,0,300,300};
856
857     *ppFrame = &InPlaceFrame;
858     *ppDoc = (IOleInPlaceUIWindow*)&InPlaceFrame;
859     *lprcPosRect = rect;
860     *lprcClipRect = rect;
861
862     lpFrameInfo->cb = sizeof(*lpFrameInfo);
863     lpFrameInfo->fMDIApp = FALSE;
864     lpFrameInfo->hwndFrame = container_hwnd;
865     lpFrameInfo->haccel = NULL;
866     lpFrameInfo->cAccelEntries = 0;
867
868     return S_OK;
869 }
870
871 static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
872 {
873     return E_NOTIMPL;
874 }
875
876 static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
877 {
878     return S_OK;
879 }
880
881 static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
882 {
883     return S_OK;
884 }
885
886 static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
887 {
888     return E_NOTIMPL;
889 }
890
891 static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
892 {
893     return E_NOTIMPL;
894 }
895
896 static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
897 {
898     return E_NOTIMPL;
899 }
900
901 static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
902     InPlaceSite_QueryInterface,
903     InPlaceSite_AddRef,
904     InPlaceSite_Release,
905     InPlaceSite_GetWindow,
906     InPlaceSite_ContextSensitiveHelp,
907     InPlaceSite_CanInPlaceActivate,
908     InPlaceSite_OnInPlaceActivate,
909     InPlaceSite_OnUIActivate,
910     InPlaceSite_GetWindowContext,
911     InPlaceSite_Scroll,
912     InPlaceSite_OnUIDeactivate,
913     InPlaceSite_OnInPlaceDeactivate,
914     InPlaceSite_DiscardUndoState,
915     InPlaceSite_DeactivateAndUndo,
916     InPlaceSite_OnPosRectChange,
917 };
918
919 static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
920
921 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
922 {
923     return QueryInterface(riid, ppv);
924 }
925
926 static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
927 {
928     return 2;
929 }
930
931 static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
932 {
933     return 1;
934 }
935
936 static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
937 {
938     ok(0, "unexpected call\n");
939     return E_NOTIMPL;
940 }
941
942 static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
943         IMoniker **ppmon)
944 {
945     ok(0, "unexpected call\n");
946     return E_NOTIMPL;
947 }
948
949 static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
950 {
951     return E_NOTIMPL;
952 }
953
954 static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
955 {
956     ok(0, "unexpected call\n");
957     return E_NOTIMPL;
958 }
959
960 static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
961 {
962     ok(0, "unexpected call\n");
963     return E_NOTIMPL;
964 }
965
966 static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
967 {
968     ok(0, "unexpected call\n");
969     return E_NOTIMPL;
970 }
971
972 static const IOleClientSiteVtbl ClientSiteVtbl = {
973     ClientSite_QueryInterface,
974     ClientSite_AddRef,
975     ClientSite_Release,
976     ClientSite_SaveObject,
977     ClientSite_GetMoniker,
978     ClientSite_GetContainer,
979     ClientSite_ShowObject,
980     ClientSite_OnShowWindow,
981     ClientSite_RequestNewObjectLayout
982 };
983
984 static IOleClientSite ClientSite = { &ClientSiteVtbl };
985
986 static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
987 {
988     return QueryInterface(riid, ppv);
989 }
990
991 static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
992 {
993     return 2;
994 }
995
996 static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
997 {
998     return 1;
999 }
1000
1001 static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
1002 {
1003     RECT rect = {0,0,300,300};
1004     IOleDocument *document;
1005     HRESULT hres;
1006
1007     hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
1008     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
1009
1010     hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
1011     IOleDocument_Release(document);
1012     ok(hres == S_OK, "CreateView failed: %08x\n", hres);
1013
1014     hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
1015     ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
1016
1017     hres = IOleDocumentView_UIActivate(view, TRUE);
1018     ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
1019
1020     hres = IOleDocumentView_SetRect(view, &rect);
1021     ok(hres == S_OK, "SetRect failed: %08x\n", hres);
1022
1023     hres = IOleDocumentView_Show(view, TRUE);
1024     ok(hres == S_OK, "Show failed: %08x\n", hres);
1025
1026     return S_OK;
1027 }
1028
1029 static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
1030     DocumentSite_QueryInterface,
1031     DocumentSite_AddRef,
1032     DocumentSite_Release,
1033     DocumentSite_ActivateMe
1034 };
1035
1036 static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
1037
1038 static HRESULT QueryInterface(REFIID riid, void **ppv)
1039 {
1040     *ppv = NULL;
1041
1042     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
1043         *ppv = &ClientSite;
1044     else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
1045         *ppv = &DocumentSite;
1046     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
1047         *ppv = &InPlaceSite;
1048     else if(IsEqualGUID(&IID_IDocHostUIHandler, riid) || IsEqualGUID(&IID_IDocHostUIHandler2, riid))
1049         *ppv = &DocHostUIHandler;
1050
1051     return *ppv ? S_OK : E_NOINTERFACE;
1052 }
1053
1054 static IHTMLDocument2 *create_document(void)
1055 {
1056     IHTMLDocument2 *doc;
1057     IHTMLDocument5 *doc5;
1058     HRESULT hres;
1059
1060     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1061             &IID_IHTMLDocument2, (void**)&doc);
1062     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
1063     if (hres != S_OK) return NULL;
1064
1065     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
1066     if(FAILED(hres)) {
1067         win_skip("Could not get IHTMLDocument5, probably too old IE\n");
1068         IHTMLDocument2_Release(doc);
1069         return NULL;
1070     }
1071
1072     IHTMLDocument5_Release(doc5);
1073     return doc;
1074 }
1075
1076 static void load_string(IHTMLDocument2 *doc, const char *str)
1077 {
1078     IPersistStreamInit *init;
1079     IStream *stream;
1080     HGLOBAL mem;
1081     SIZE_T len;
1082
1083     doc_complete = FALSE;
1084     len = strlen(str);
1085     mem = GlobalAlloc(0, len);
1086     memcpy(mem, str, len);
1087     CreateStreamOnHGlobal(mem, TRUE, &stream);
1088
1089     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
1090
1091     IPersistStreamInit_Load(init, stream);
1092     IPersistStreamInit_Release(init);
1093     IStream_Release(stream);
1094 }
1095
1096 static void do_advise(IHTMLDocument2 *doc, REFIID riid, IUnknown *unk_advise)
1097 {
1098     IConnectionPointContainer *container;
1099     IConnectionPoint *cp;
1100     DWORD cookie;
1101     HRESULT hres;
1102
1103     hres = IHTMLDocument2_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&container);
1104     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
1105
1106     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
1107     IConnectionPointContainer_Release(container);
1108     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
1109
1110     notif_doc = doc;
1111
1112     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
1113     IConnectionPoint_Release(cp);
1114     ok(hres == S_OK, "Advise failed: %08x\n", hres);
1115 }
1116
1117 static void set_client_site(IHTMLDocument2 *doc, BOOL set)
1118 {
1119     IOleObject *oleobj;
1120     HRESULT hres;
1121
1122     if(!set && view) {
1123         IOleDocumentView_Show(view, FALSE);
1124         IOleDocumentView_CloseView(view, 0);
1125         IOleDocumentView_SetInPlaceSite(view, NULL);
1126         IOleDocumentView_Release(view);
1127         view = NULL;
1128     }
1129
1130     hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj);
1131     ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres);
1132
1133     hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL);
1134     ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
1135
1136     if(set) {
1137         IHlinkTarget *hlink;
1138
1139         hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink);
1140         ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres);
1141
1142         hres = IHlinkTarget_Navigate(hlink, 0, NULL);
1143         ok(hres == S_OK, "Navgate failed: %08x\n", hres);
1144
1145         IHlinkTarget_Release(hlink);
1146     }
1147
1148     IOleObject_Release(oleobj);
1149 }
1150
1151 typedef void (*domtest_t)(IHTMLDocument2*);
1152
1153 static void load_doc(IHTMLDocument2 *doc, const char *str)
1154 {
1155     IHTMLElement *body = NULL;
1156     MSG msg;
1157     HRESULT hres;
1158     static const WCHAR ucPtr[] = {'b','a','c','k','g','r','o','u','n','d',0};
1159     DISPID dispID = -1;
1160     OLECHAR *name;
1161
1162     load_string(doc, str);
1163     do_advise(doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
1164
1165     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
1166         TranslateMessage(&msg);
1167         DispatchMessage(&msg);
1168     }
1169
1170     hres = IHTMLDocument2_get_body(doc, &body);
1171     ok(hres == S_OK, "get_body failed: %08x\n", hres);
1172
1173     /* Check we can query for function on the IHTMLElementBody interface */
1174     name = (WCHAR*)ucPtr;
1175     hres = IHTMLElement_GetIDsOfNames(body, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispID);
1176     ok(hres == S_OK, "GetIDsOfNames(background) failed %08x\n", hres);
1177     ok(dispID == DISPID_IHTMLBODYELEMENT_BACKGROUND, "Incorrect dispID got (%d)\n", dispID);
1178
1179     IHTMLElement_Release(body);
1180 }
1181
1182 static IActiveScriptSite *site;
1183 static SCRIPTSTATE state;
1184
1185 static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1186 {
1187     *ppv = NULL;
1188     ok(0, "unexpected call %s\n", debugstr_guid(riid));
1189     return E_NOINTERFACE;
1190 }
1191
1192 static ULONG WINAPI ObjectSafety_AddRef(IObjectSafety *iface)
1193 {
1194     return 2;
1195 }
1196
1197 static ULONG WINAPI ObjectSafety_Release(IObjectSafety *iface)
1198 {
1199     return 1;
1200 }
1201
1202 static HRESULT WINAPI ObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1203         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1204 {
1205     CHECK_EXPECT(GetInterfaceSafetyOptions);
1206
1207     ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", debugstr_guid(riid));
1208     ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n");
1209     ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n");
1210
1211     *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
1212     *pdwEnabledOptions = INTERFACE_USES_DISPEX;
1213
1214     return S_OK;
1215 }
1216
1217 static HRESULT WINAPI ObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1218         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1219 {
1220     CHECK_EXPECT(SetInterfaceSafetyOptions);
1221
1222     ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", debugstr_guid(riid));
1223
1224     ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
1225        "dwOptionSetMask=%x\n", dwOptionSetMask);
1226     ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
1227        "dwEnabledOptions=%x\n", dwOptionSetMask);
1228
1229     return S_OK;
1230 }
1231
1232 static const IObjectSafetyVtbl ObjectSafetyVtbl = {
1233     ObjectSafety_QueryInterface,
1234     ObjectSafety_AddRef,
1235     ObjectSafety_Release,
1236     ObjectSafety_GetInterfaceSafetyOptions,
1237     ObjectSafety_SetInterfaceSafetyOptions
1238 };
1239
1240 static IObjectSafety ObjectSafety = { &ObjectSafetyVtbl };
1241
1242 static HRESULT WINAPI AXObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
1243 {
1244     *ppv = NULL;
1245
1246     if(IsEqualGUID(&IID_IActiveScript, riid)) {
1247         CHECK_EXPECT(AXQueryInterface_IActiveScript);
1248         return E_NOINTERFACE;
1249     }
1250
1251     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
1252         CHECK_EXPECT(AXQueryInterface_IObjectSafety);
1253         if(!ax_objsafe)
1254             return E_NOINTERFACE;
1255         *ppv = iface;
1256         return S_OK;
1257     }
1258
1259     ok(0, "unexpected call %s\n", debugstr_guid(riid));
1260     return E_NOINTERFACE;
1261 }
1262
1263 static HRESULT WINAPI AXObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1264         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
1265 {
1266     CHECK_EXPECT(AXGetInterfaceSafetyOptions);
1267
1268     ok(IsEqualGUID(&IID_IDispatchEx, riid), "unexpected riid %s\n", debugstr_guid(riid));
1269     ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n");
1270     ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n");
1271
1272     if(SUCCEEDED(ax_getopt_hres)) {
1273         *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
1274         *pdwEnabledOptions = INTERFACE_USES_DISPEX;
1275     }
1276
1277     return ax_getopt_hres;
1278 }
1279
1280 static HRESULT WINAPI AXObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
1281         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
1282 {
1283     if(IsEqualGUID(&IID_IDispatchEx, riid)) {
1284         CHECK_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx);
1285         ok(dwOptionSetMask == ax_setopt, "dwOptionSetMask=%x, expected %x\n", dwOptionSetMask, ax_setopt);
1286         ok(dwEnabledOptions == ax_setopt, "dwEnabledOptions=%x, expected %x\n", dwOptionSetMask, ax_setopt);
1287         return ax_setopt_dispex_hres;
1288     }
1289
1290     if(IsEqualGUID(&IID_IDispatch, riid)) {
1291         DWORD exopt = ax_setopt & ~INTERFACE_USES_SECURITY_MANAGER;
1292
1293         CHECK_EXPECT(AXSetInterfaceSafetyOptions_IDispatch);
1294         ok(dwOptionSetMask == exopt, "dwOptionSetMask=%x, expected %x\n", dwOptionSetMask, exopt);
1295         ok(dwEnabledOptions == exopt, "dwEnabledOptions=%x, expected %x\n", dwOptionSetMask, exopt);
1296         return ax_setopt_disp_hres;
1297     }
1298
1299     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1300     return E_NOINTERFACE;
1301 }
1302
1303 static const IObjectSafetyVtbl AXObjectSafetyVtbl = {
1304     AXObjectSafety_QueryInterface,
1305     ObjectSafety_AddRef,
1306     ObjectSafety_Release,
1307     AXObjectSafety_GetInterfaceSafetyOptions,
1308     AXObjectSafety_SetInterfaceSafetyOptions
1309 };
1310
1311 static IObjectSafety AXObjectSafety = { &AXObjectSafetyVtbl };
1312
1313 static BOOL set_safe_reg(BOOL init)
1314 {
1315     return init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95801-9882-11cf-9fa9-00aa006c42c4}",
1316                     NULL, init);
1317 }
1318
1319 static void test_security(void)
1320 {
1321     IInternetHostSecurityManager *sec_mgr;
1322     IServiceProvider *sp;
1323     DWORD policy, policy_size;
1324     struct CONFIRMSAFETY cs;
1325     BYTE *ppolicy;
1326     HRESULT hres;
1327
1328     ax_setopt = INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACE_USES_SECURITY_MANAGER;
1329
1330     hres = IActiveScriptSite_QueryInterface(site, &IID_IServiceProvider, (void**)&sp);
1331     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
1332
1333     hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager,
1334             &IID_IInternetHostSecurityManager, (void**)&sec_mgr);
1335     IServiceProvider_Release(sp);
1336     ok(hres == S_OK, "QueryService failed: %08x\n", hres);
1337
1338     hres = IInternetHostSecurityManager_ProcessUrlAction(sec_mgr, URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy),
1339                                                          (BYTE*)&CLSID_TestActiveX, sizeof(CLSID), 0, 0);
1340     ok(hres == S_OK, "ProcessUrlAction failed: %08x\n", hres);
1341     ok(policy == URLPOLICY_ALLOW, "policy = %x\n", policy);
1342
1343     cs.clsid = CLSID_TestActiveX;
1344     cs.pUnk = (IUnknown*)&AXObjectSafety;
1345     cs.dwFlags = 0;
1346
1347     ax_objsafe = TRUE;
1348     SET_EXPECT(AXQueryInterface_IActiveScript);
1349     SET_EXPECT(AXQueryInterface_IObjectSafety);
1350     SET_EXPECT(AXGetInterfaceSafetyOptions);
1351     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx);
1352     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1353             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1354     CHECK_CALLED(AXQueryInterface_IActiveScript);
1355     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1356     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1357     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx);
1358
1359     ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
1360     ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
1361     ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
1362     CoTaskMemFree(ppolicy);
1363
1364     ax_objsafe = FALSE;
1365     SET_EXPECT(AXQueryInterface_IActiveScript);
1366     SET_EXPECT(AXQueryInterface_IObjectSafety);
1367     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1368             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1369     CHECK_CALLED(AXQueryInterface_IActiveScript);
1370     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1371
1372     ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
1373     ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
1374     ok(*(DWORD*)ppolicy == URLPOLICY_DISALLOW, "policy = %x\n", *(DWORD*)ppolicy);
1375     CoTaskMemFree(ppolicy);
1376
1377     if(set_safe_reg(TRUE)) {
1378         ax_objsafe = FALSE;
1379         SET_EXPECT(AXQueryInterface_IActiveScript);
1380         SET_EXPECT(AXQueryInterface_IObjectSafety);
1381         hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1382                  &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1383         CHECK_CALLED(AXQueryInterface_IActiveScript);
1384         CHECK_CALLED(AXQueryInterface_IObjectSafety);
1385
1386         ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
1387         ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
1388         ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
1389         CoTaskMemFree(ppolicy);
1390
1391         ax_objsafe = TRUE;
1392         SET_EXPECT(AXQueryInterface_IActiveScript);
1393         SET_EXPECT(AXQueryInterface_IObjectSafety);
1394         SET_EXPECT(AXGetInterfaceSafetyOptions);
1395         SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx);
1396         hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1397                 &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1398         CHECK_CALLED(AXQueryInterface_IActiveScript);
1399         CHECK_CALLED(AXQueryInterface_IObjectSafety);
1400         CHECK_CALLED(AXGetInterfaceSafetyOptions);
1401         CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx);
1402
1403         ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
1404         ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
1405         ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
1406         CoTaskMemFree(ppolicy);
1407
1408         set_safe_reg(FALSE);
1409     }else {
1410         skip("Could not set safety registry\n");
1411     }
1412
1413     ax_objsafe = TRUE;
1414
1415     ax_setopt_dispex_hres = E_NOINTERFACE;
1416     SET_EXPECT(AXQueryInterface_IActiveScript);
1417     SET_EXPECT(AXQueryInterface_IObjectSafety);
1418     SET_EXPECT(AXGetInterfaceSafetyOptions);
1419     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx);
1420     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch);
1421     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1422             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1423     CHECK_CALLED(AXQueryInterface_IActiveScript);
1424     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1425     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1426     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx);
1427     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch);
1428
1429     ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
1430     ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
1431     ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
1432     CoTaskMemFree(ppolicy);
1433
1434     ax_setopt_dispex_hres = E_FAIL;
1435     ax_setopt_disp_hres = E_NOINTERFACE;
1436     SET_EXPECT(AXQueryInterface_IActiveScript);
1437     SET_EXPECT(AXQueryInterface_IObjectSafety);
1438     SET_EXPECT(AXGetInterfaceSafetyOptions);
1439     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx);
1440     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch);
1441     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1442             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1443     CHECK_CALLED(AXQueryInterface_IActiveScript);
1444     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1445     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1446     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx);
1447     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch);
1448
1449     ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
1450     ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
1451     ok(*(DWORD*)ppolicy == URLPOLICY_DISALLOW, "policy = %x\n", *(DWORD*)ppolicy);
1452     CoTaskMemFree(ppolicy);
1453
1454     ax_setopt_dispex_hres = E_FAIL;
1455     ax_setopt_disp_hres = S_OK;
1456     ax_getopt_hres = E_NOINTERFACE;
1457     ax_setopt = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
1458     SET_EXPECT(AXQueryInterface_IActiveScript);
1459     SET_EXPECT(AXQueryInterface_IObjectSafety);
1460     SET_EXPECT(AXGetInterfaceSafetyOptions);
1461     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatchEx);
1462     SET_EXPECT(AXSetInterfaceSafetyOptions_IDispatch);
1463     hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
1464             &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
1465     CHECK_CALLED(AXQueryInterface_IActiveScript);
1466     CHECK_CALLED(AXQueryInterface_IObjectSafety);
1467     CHECK_CALLED(AXGetInterfaceSafetyOptions);
1468     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatchEx);
1469     CHECK_CALLED(AXSetInterfaceSafetyOptions_IDispatch);
1470
1471     ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
1472     ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
1473     ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
1474     CoTaskMemFree(ppolicy);
1475
1476     IInternetHostSecurityManager_Release(sec_mgr);
1477 }
1478
1479 static HRESULT WINAPI ActiveScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
1480 {
1481     *ppv = NULL;
1482     ok(0, "unexpected call\n");
1483     return E_NOINTERFACE;
1484 }
1485
1486 static ULONG WINAPI ActiveScriptProperty_AddRef(IActiveScriptProperty *iface)
1487 {
1488     return 2;
1489 }
1490
1491 static ULONG WINAPI ActiveScriptProperty_Release(IActiveScriptProperty *iface)
1492 {
1493     return 1;
1494 }
1495
1496 static HRESULT WINAPI ActiveScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
1497         VARIANT *pvarIndex, VARIANT *pvarValue)
1498 {
1499     ok(0, "unexpected call\n");
1500     return E_NOTIMPL;
1501 }
1502
1503 static HRESULT WINAPI ActiveScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
1504         VARIANT *pvarIndex, VARIANT *pvarValue)
1505 {
1506     switch(dwProperty) {
1507     case SCRIPTPROP_HACK_TRIDENTEVENTSINK:
1508         CHECK_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
1509         ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
1510         ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue));
1511         break;
1512     case SCRIPTPROP_INVOKEVERSIONING:
1513         CHECK_EXPECT(SetProperty_INVOKEVERSIONING);
1514         ok(V_VT(pvarValue) == VT_I4, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
1515         ok(V_I4(pvarValue) == 1, "V_I4(pvarValue)=%d\n", V_I4(pvarValue));
1516         break;
1517     case SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION:
1518         CHECK_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION);
1519         ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
1520         ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue));
1521         break;
1522     default:
1523         ok(0, "unexpected property %x\n", dwProperty);
1524         return E_NOTIMPL;
1525     }
1526
1527     ok(!pvarIndex, "pvarIndex != NULL\n");
1528     ok(pvarValue != NULL, "pvarValue == NULL\n");
1529
1530     return S_OK;
1531 }
1532
1533 static const IActiveScriptPropertyVtbl ActiveScriptPropertyVtbl = {
1534     ActiveScriptProperty_QueryInterface,
1535     ActiveScriptProperty_AddRef,
1536     ActiveScriptProperty_Release,
1537     ActiveScriptProperty_GetProperty,
1538     ActiveScriptProperty_SetProperty
1539 };
1540
1541 static IActiveScriptProperty ActiveScriptProperty = { &ActiveScriptPropertyVtbl };
1542
1543 static HRESULT WINAPI ActiveScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
1544 {
1545     *ppv = NULL;
1546     ok(0, "unexpected call\n");
1547     return E_NOINTERFACE;
1548 }
1549
1550 static ULONG WINAPI ActiveScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
1551 {
1552     return 2;
1553 }
1554
1555 static ULONG WINAPI ActiveScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
1556 {
1557     return 1;
1558 }
1559
1560 static HRESULT WINAPI ActiveScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
1561         LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
1562         LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
1563         CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
1564 {
1565     ok(0, "unexpected call\n");
1566     return E_NOTIMPL;
1567 }
1568
1569 static const IActiveScriptParseProcedure2Vtbl ActiveScriptParseProcedureVtbl = {
1570     ActiveScriptParseProcedure_QueryInterface,
1571     ActiveScriptParseProcedure_AddRef,
1572     ActiveScriptParseProcedure_Release,
1573     ActiveScriptParseProcedure_ParseProcedureText
1574 };
1575
1576 static IActiveScriptParseProcedure2 ActiveScriptParseProcedure = { &ActiveScriptParseProcedureVtbl };
1577
1578 static HRESULT WINAPI ActiveScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
1579 {
1580     *ppv = NULL;
1581     ok(0, "unexpected call\n");
1582     return E_NOINTERFACE;
1583 }
1584
1585 static ULONG WINAPI ActiveScriptParse_AddRef(IActiveScriptParse *iface)
1586 {
1587     return 2;
1588 }
1589
1590 static ULONG WINAPI ActiveScriptParse_Release(IActiveScriptParse *iface)
1591 {
1592     return 1;
1593 }
1594
1595 static HRESULT WINAPI ActiveScriptParse_InitNew(IActiveScriptParse *iface)
1596 {
1597     CHECK_EXPECT(InitNew);
1598     return S_OK;
1599 }
1600
1601 static HRESULT WINAPI ActiveScriptParse_AddScriptlet(IActiveScriptParse *iface,
1602         LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
1603         LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
1604         CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
1605         BSTR *pbstrName, EXCEPINFO *pexcepinfo)
1606 {
1607     ok(0, "unexpected call\n");
1608     return E_NOTIMPL;
1609 }
1610
1611 static HRESULT dispex_propput(IDispatchEx *obj, DISPID id, DWORD flags, VARIANT *var)
1612 {
1613     DISPID propput_arg = DISPID_PROPERTYPUT;
1614     DISPPARAMS dp = {var, &propput_arg, 1, 1};
1615     EXCEPINFO ei = {0};
1616
1617     return IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT|flags, &dp, NULL, &ei, NULL);
1618 }
1619
1620 static void test_func(IDispatchEx *obj)
1621 {
1622     DISPID id;
1623     IDispatchEx *dispex;
1624     IDispatch *disp;
1625     EXCEPINFO ei;
1626     DISPPARAMS dp;
1627     BSTR str;
1628     VARIANT var;
1629     HRESULT hres;
1630
1631     str = a2bstr("toString");
1632     hres = IDispatchEx_GetDispID(obj, str, fdexNameCaseSensitive, &id);
1633     SysFreeString(str);
1634     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1635     ok(id == DISPID_IOMNAVIGATOR_TOSTRING, "id = %x\n", id);
1636
1637     memset(&dp, 0, sizeof(dp));
1638     memset(&ei, 0, sizeof(ei));
1639     VariantInit(&var);
1640     hres = IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
1641     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1642     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
1643     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
1644     disp = V_DISPATCH(&var);
1645
1646     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
1647     IDispatch_Release(disp);
1648     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1649
1650     /* FIXME: Test InvokeEx(DISPATCH_METHOD) */
1651
1652     memset(&dp, 0, sizeof(dp));
1653     memset(&ei, 0, sizeof(ei));
1654     VariantInit(&var);
1655     hres = IDispatchEx_Invoke(dispex, DISPID_VALUE, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &var, &ei, NULL);
1656     ok(hres == S_OK || broken(E_ACCESSDENIED), "InvokeEx failed: %08x\n", hres);
1657     if(SUCCEEDED(hres)) {
1658         ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
1659         ok(!strcmp_wa(V_BSTR(&var), "[object]"), "V_BSTR(var) = %s\n", wine_dbgstr_w(V_BSTR(&var)));
1660         VariantClear(&var);
1661     }
1662
1663     V_VT(&var) = VT_I4;
1664     V_I4(&var) = 100;
1665     hres = dispex_propput(obj, id, 0, &var);
1666     ok(hres == E_NOTIMPL, "InvokeEx failed: %08x\n", hres);
1667
1668     IDispatchEx_Release(dispex);
1669 }
1670
1671 static void test_nextdispid(IDispatchEx *dispex)
1672 {
1673     DISPID last_id = DISPID_STARTENUM, id, dyn_id;
1674     BSTR name;
1675     VARIANT var;
1676     HRESULT hres;
1677
1678     name = a2bstr("dynVal");
1679     hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseSensitive|fdexNameEnsure, &dyn_id);
1680     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1681     SysFreeString(name);
1682
1683     V_VT(&var) = VT_EMPTY;
1684     hres = dispex_propput(dispex, dyn_id, 0, &var);
1685
1686     while(last_id != dyn_id) {
1687         hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, last_id, &id);
1688         ok(hres == S_OK, "GetNextDispID returned: %08x\n", hres);
1689         ok(id != DISPID_STARTENUM, "id == DISPID_STARTENUM\n");
1690         ok(id != DISPID_IOMNAVIGATOR_TOSTRING, "id == DISPID_IOMNAVIGATOR_TOSTRING\n");
1691
1692         hres = IDispatchEx_GetMemberName(dispex, id, &name);
1693         ok(hres == S_OK, "GetMemberName failed: %08x\n", hres);
1694
1695         if(id == dyn_id)
1696             ok(!strcmp_wa(name, "dynVal"), "name = %s\n", wine_dbgstr_w(name));
1697         else if(id == DISPID_IOMNAVIGATOR_PLATFORM)
1698             ok(!strcmp_wa(name, "platform"), "name = %s\n", wine_dbgstr_w(name));
1699
1700         SysFreeString(name);
1701         last_id = id;
1702     }
1703
1704     hres = IDispatchEx_GetNextDispID(dispex, 0, id, &id);
1705     ok(hres == S_FALSE, "GetNextDispID returned: %08x\n", hres);
1706     ok(id == DISPID_STARTENUM, "id != DISPID_STARTENUM\n");
1707 }
1708
1709 static void test_global_id(void)
1710 {
1711     VARIANT var;
1712     DISPPARAMS dp;
1713     EXCEPINFO ei;
1714     BSTR tmp;
1715     DISPID id;
1716     HRESULT hres;
1717
1718     SET_EXPECT(GetScriptDispatch);
1719     SET_EXPECT(script_divid_d);
1720     tmp = a2bstr("divid");
1721     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1722     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1723     SysFreeString(tmp);
1724     CHECK_CALLED(GetScriptDispatch);
1725     CHECK_CALLED(script_divid_d);
1726
1727     VariantInit(&var);
1728     memset(&ei, 0, sizeof(ei));
1729     memset(&dp, 0, sizeof(dp));
1730     hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
1731     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1732     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var) = %d\n", V_VT(&var));
1733     VariantClear(&var);
1734 }
1735
1736 static void test_script_run(void)
1737 {
1738     IDispatchEx *document, *dispex;
1739     IHTMLWindow2 *window;
1740     IOmNavigator *navigator;
1741     IUnknown *unk;
1742     VARIANT var, arg;
1743     DISPPARAMS dp;
1744     EXCEPINFO ei;
1745     DISPID id;
1746     BSTR tmp;
1747     HRESULT hres;
1748
1749     static const WCHAR documentW[] = {'d','o','c','u','m','e','n','t',0};
1750     static const WCHAR testW[] = {'t','e','s','t',0};
1751     static const WCHAR funcW[] = {'f','u','n','c',0};
1752
1753     SET_EXPECT(GetScriptDispatch);
1754
1755     tmp = SysAllocString(documentW);
1756     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1757     SysFreeString(tmp);
1758     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
1759     ok(id == DISPID_IHTMLWINDOW2_DOCUMENT, "id=%x\n", id);
1760
1761     CHECK_CALLED(GetScriptDispatch);
1762
1763     VariantInit(&var);
1764     memset(&dp, 0, sizeof(dp));
1765     memset(&ei, 0, sizeof(ei));
1766
1767     hres = IDispatchEx_InvokeEx(window_dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
1768     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1769     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
1770     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(&var) == NULL\n");
1771
1772     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDispatchEx, (void**)&document);
1773     VariantClear(&var);
1774     ok(hres == S_OK, "Could not get DispatchEx: %08x\n", hres);
1775
1776     tmp = SysAllocString(testW);
1777     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
1778     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
1779     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive | fdexNameImplicit, &id);
1780     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
1781     SysFreeString(tmp);
1782
1783     id = 0;
1784     tmp = SysAllocString(testW);
1785     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
1786     SysFreeString(tmp);
1787     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
1788     ok(id, "id == 0\n");
1789
1790     V_VT(&var) = VT_I4;
1791     V_I4(&var) = 100;
1792     hres = dispex_propput(document, id, 0, &var);
1793     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1794
1795     tmp = SysAllocString(testW);
1796     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
1797     SysFreeString(tmp);
1798     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
1799
1800     VariantInit(&var);
1801     memset(&dp, 0, sizeof(dp));
1802     memset(&ei, 0, sizeof(ei));
1803     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
1804     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1805     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
1806     ok(V_I4(&var) == 100, "V_I4(&var) = %d\n", V_I4(&var));
1807
1808     V_VT(&var) = VT_I4;
1809     V_I4(&var) = 200;
1810     hres = dispex_propput(document, id, DISPATCH_PROPERTYPUTREF, &var);
1811     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1812
1813     VariantInit(&var);
1814     memset(&dp, 0, sizeof(dp));
1815     memset(&ei, 0, sizeof(ei));
1816     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
1817     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1818     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
1819     ok(V_I4(&var) == 200, "V_I4(&var) = %d\n", V_I4(&var));
1820
1821     memset(&dp, 0, sizeof(dp));
1822     memset(&ei, 0, sizeof(ei));
1823     V_VT(&var) = VT_I4;
1824     V_I4(&var) = 300;
1825     dp.cArgs = 1;
1826     dp.rgvarg = &var;
1827     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
1828     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1829
1830     VariantInit(&var);
1831     memset(&dp, 0, sizeof(dp));
1832     memset(&ei, 0, sizeof(ei));
1833     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
1834     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1835     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
1836     ok(V_I4(&var) == 300, "V_I4(&var) = %d\n", V_I4(&var));
1837
1838     unk = (void*)0xdeadbeef;
1839     hres = IDispatchEx_GetNameSpaceParent(window_dispex, &unk);
1840     ok(hres == S_OK, "GetNameSpaceParent failed: %08x\n", hres);
1841     ok(!unk, "unk=%p, expected NULL\n", unk);
1842
1843     id = 0;
1844     tmp = SysAllocString(funcW);
1845     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
1846     SysFreeString(tmp);
1847     ok(hres == S_OK, "GetDispID(func) failed: %08x\n", hres);
1848     ok(id, "id == 0\n");
1849
1850     dp.cArgs = 1;
1851     dp.rgvarg = &var;
1852     dp.cNamedArgs = 0;
1853     dp.rgdispidNamedArgs = NULL;
1854     V_VT(&var) = VT_DISPATCH;
1855     V_DISPATCH(&var) = (IDispatch*)&funcDisp;
1856     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
1857     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1858
1859     VariantInit(&var);
1860     memset(&dp, 0, sizeof(dp));
1861     memset(&ei, 0, sizeof(ei));
1862     V_VT(&arg) = VT_BOOL;
1863     V_BOOL(&arg) = VARIANT_TRUE;
1864     dp.cArgs = 1;
1865     dp.rgvarg = &arg;
1866
1867     SET_EXPECT(funcDisp);
1868     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_FUNC, &dp, &var, &ei, NULL);
1869     CHECK_CALLED(funcDisp);
1870
1871     ok(hres == S_OK, "InvokeEx(INVOKE_FUNC) failed: %08x\n", hres);
1872     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
1873     ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
1874
1875     IDispatchEx_Release(document);
1876
1877     hres = IDispatchEx_QueryInterface(window_dispex, &IID_IHTMLWindow2, (void**)&window);
1878     ok(hres == S_OK, "Could not get IHTMLWindow2 iface: %08x\n", hres);
1879
1880     hres = IHTMLWindow2_get_navigator(window, &navigator);
1881     IHTMLWindow2_Release(window);
1882     ok(hres == S_OK, "get_navigator failed: %08x\n", hres);
1883
1884     hres = IOmNavigator_QueryInterface(navigator, &IID_IDispatchEx, (void**)&dispex);
1885     IOmNavigator_Release(navigator);
1886     ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
1887
1888     test_func(dispex);
1889     test_nextdispid(dispex);
1890
1891     tmp = a2bstr("test");
1892     hres = IDispatchEx_DeleteMemberByName(dispex, tmp, fdexNameCaseSensitive);
1893     ok(hres == E_NOTIMPL, "DeleteMemberByName failed: %08x\n", hres);
1894
1895     IDispatchEx_Release(dispex);
1896
1897     script_disp = (IDispatch*)&scriptDisp;
1898
1899     SET_EXPECT(GetScriptDispatch);
1900     SET_EXPECT(script_testprop_d);
1901     tmp = a2bstr("testProp");
1902     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1903     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1904     ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n");
1905     CHECK_CALLED(GetScriptDispatch);
1906     CHECK_CALLED(script_testprop_d);
1907     SysFreeString(tmp);
1908
1909     tmp = a2bstr("testProp");
1910     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
1911     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1912     ok(id != DISPID_SCRIPT_TESTPROP, "id == DISPID_SCRIPT_TESTPROP\n");
1913     SysFreeString(tmp);
1914
1915     SET_EXPECT(GetScriptDispatch);
1916     SET_EXPECT(script_testprop_i);
1917     memset(&ei, 0, sizeof(ei));
1918     memset(&dp, 0, sizeof(dp));
1919     hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
1920     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
1921     ok(V_VT(&var) == VT_NULL, "V_VT(var) = %d\n", V_VT(&var));
1922     CHECK_CALLED(GetScriptDispatch);
1923     CHECK_CALLED(script_testprop_i);
1924
1925     SET_EXPECT(GetScriptDispatch);
1926     SET_EXPECT(script_testprop2_d);
1927     tmp = a2bstr("testProp2");
1928     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
1929     ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
1930     ok(id != DISPID_SCRIPT_TESTPROP2, "id == DISPID_SCRIPT_TESTPROP2\n");
1931     CHECK_CALLED(GetScriptDispatch);
1932     CHECK_CALLED(script_testprop2_d);
1933     SysFreeString(tmp);
1934
1935     tmp = a2bstr("test");
1936     hres = IDispatchEx_DeleteMemberByName(window_dispex, tmp, fdexNameCaseSensitive);
1937     ok(hres == E_NOTIMPL, "DeleteMemberByName failed: %08x\n", hres);
1938
1939     test_global_id();
1940
1941     test_security();
1942 }
1943
1944 static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
1945         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
1946         LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
1947         DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
1948 {
1949     ok(!punkContext, "punkContext = %p\n", punkContext);
1950     ok(pvarResult != NULL, "pvarResult == NULL\n");
1951     ok(pexcepinfo != NULL, "pexcepinfo == NULL\n");
1952
1953     if(!strcmp_wa(pstrCode, "execScript call")) {
1954         CHECK_EXPECT(ParseScriptText_execScript);
1955         ok(!pstrItemName, "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
1956         ok(!strcmp_wa(pstrDelimiter, "\""), "pstrDelimiter = %s\n", wine_dbgstr_w(pstrDelimiter));
1957         ok(dwFlags == SCRIPTTEXT_ISVISIBLE, "dwFlags = %x\n", dwFlags);
1958
1959         V_VT(pvarResult) = VT_I4;
1960         V_I4(pvarResult) = 10;
1961         return S_OK;
1962     }else if(!strcmp_wa(pstrCode, "simple script")) {
1963         CHECK_EXPECT(ParseScriptText_script);
1964         ok(!strcmp_wa(pstrItemName, "window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
1965         ok(!strcmp_wa(pstrDelimiter, "</SCRIPT>"), "pstrDelimiter = %s\n", wine_dbgstr_w(pstrDelimiter));
1966         ok(dwFlags == (SCRIPTTEXT_ISVISIBLE|SCRIPTTEXT_HOSTMANAGESSOURCE), "dwFlags = %x\n", dwFlags);
1967
1968         test_script_run();
1969         return S_OK;
1970     }
1971
1972     ok(0, "unexpected script %s\n", wine_dbgstr_w(pstrCode));
1973     return E_FAIL;
1974 }
1975
1976 static const IActiveScriptParseVtbl ActiveScriptParseVtbl = {
1977     ActiveScriptParse_QueryInterface,
1978     ActiveScriptParse_AddRef,
1979     ActiveScriptParse_Release,
1980     ActiveScriptParse_InitNew,
1981     ActiveScriptParse_AddScriptlet,
1982     ActiveScriptParse_ParseScriptText
1983 };
1984
1985 static IActiveScriptParse ActiveScriptParse = { &ActiveScriptParseVtbl };
1986
1987 static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
1988 {
1989     *ppv = NULL;
1990
1991     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IActiveScript, riid)) {
1992         *ppv = iface;
1993         return S_OK;
1994     }
1995
1996     if(IsEqualGUID(&IID_IActiveScriptParse, riid)) {
1997         *ppv = &ActiveScriptParse;
1998         return S_OK;
1999     }
2000
2001     if(IsEqualGUID(&IID_IActiveScriptParseProcedure2, riid)) {
2002         *ppv = &ActiveScriptParseProcedure;
2003         return S_OK;
2004     }
2005
2006     if(IsEqualGUID(&IID_IActiveScriptProperty, riid)) {
2007         *ppv = &ActiveScriptProperty;
2008         return S_OK;
2009     }
2010
2011     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
2012         *ppv = &ObjectSafety;
2013         return S_OK;
2014     }
2015
2016     if(IsEqualGUID(&IID_IActiveScriptDebug, riid))
2017         return E_NOINTERFACE;
2018
2019     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2020     return E_NOINTERFACE;
2021 }
2022
2023 static ULONG WINAPI ActiveScript_AddRef(IActiveScript *iface)
2024 {
2025     return 2;
2026 }
2027
2028 static ULONG WINAPI ActiveScript_Release(IActiveScript *iface)
2029 {
2030     return 1;
2031 }
2032
2033 static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
2034 {
2035     IActiveScriptSiteInterruptPoll *poll;
2036     IActiveScriptSiteDebug *debug;
2037     IServiceProvider *service;
2038     ICanHandleException *canexpection;
2039     LCID lcid;
2040     HRESULT hres;
2041
2042     CHECK_EXPECT(SetScriptSite);
2043
2044     ok(pass != NULL, "pass == NULL\n");
2045
2046     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteInterruptPoll, (void**)&poll);
2047     ok(hres == S_OK, "Could not get IActiveScriptSiteInterruptPoll interface: %08x\n", hres);
2048     if(FAILED(hres))
2049         IActiveScriptSiteInterruptPoll_Release(poll);
2050
2051     hres = IActiveScriptSite_GetLCID(pass, &lcid);
2052     ok(hres == S_OK, "GetLCID failed: %08x\n", hres);
2053
2054     hres = IActiveScriptSite_OnStateChange(pass, (state = SCRIPTSTATE_INITIALIZED));
2055     ok(hres == S_OK, "OnStateChange failed: %08x\n", hres);
2056
2057     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteDebug, (void**)&debug);
2058     ok(hres == S_OK, "Could not get IActiveScriptSiteDebug interface: %08x\n", hres);
2059     if(SUCCEEDED(hres))
2060         IActiveScriptSiteDebug32_Release(debug);
2061
2062     hres = IActiveScriptSite_QueryInterface(pass, &IID_ICanHandleException, (void**)&canexpection);
2063     ok(hres == E_NOINTERFACE, "Could not get IID_ICanHandleException interface: %08x\n", hres);
2064
2065     hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service);
2066     ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
2067     if(SUCCEEDED(hres))
2068         IServiceProvider_Release(service);
2069
2070     site = pass;
2071     IActiveScriptSite_AddRef(site);
2072     return S_OK;
2073 }
2074
2075 static HRESULT WINAPI ActiveScript_GetScriptSite(IActiveScript *iface, REFIID riid,
2076                                             void **ppvObject)
2077 {
2078     ok(0, "unexpected call\n");
2079     return E_NOTIMPL;
2080 }
2081
2082 static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
2083 {
2084     HRESULT hres;
2085
2086     switch(ss) {
2087     case SCRIPTSTATE_STARTED:
2088         CHECK_EXPECT(SetScriptState_STARTED);
2089         break;
2090     case SCRIPTSTATE_CONNECTED:
2091         CHECK_EXPECT(SetScriptState_CONNECTED);
2092         break;
2093     case SCRIPTSTATE_DISCONNECTED:
2094         CHECK_EXPECT(SetScriptState_DISCONNECTED);
2095         break;
2096     default:
2097         ok(0, "unexpected state %d\n", ss);
2098         return E_NOTIMPL;
2099     }
2100
2101     hres = IActiveScriptSite_OnStateChange(site, (state = ss));
2102     ok(hres == S_OK, "OnStateChange failed: %08x\n", hres);
2103
2104     return S_OK;
2105 }
2106
2107 static HRESULT WINAPI ActiveScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
2108 {
2109     CHECK_EXPECT(GetScriptState);
2110
2111     *pssState = state;
2112     return S_OK;
2113 }
2114
2115 static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface)
2116 {
2117     CHECK_EXPECT(Close);
2118     return E_NOTIMPL;
2119 }
2120
2121 static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface,
2122         LPCOLESTR pstrName, DWORD dwFlags)
2123 {
2124     IDispatch *disp;
2125     IUnknown *unk = NULL, *unk2;
2126     HRESULT hres;
2127
2128     static const WCHAR windowW[] = {'w','i','n','d','o','w',0};
2129
2130     static const IID unknown_iid = {0x719C3050,0xF9D3,0x11CF,{0xA4,0x93,0x00,0x40,0x05,0x23,0xA8,0xA0}};
2131
2132     CHECK_EXPECT(AddNamedItem);
2133
2134     ok(!lstrcmpW(pstrName, windowW), "pstrName=%s\n", wine_dbgstr_w(pstrName));
2135     ok(dwFlags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS), "dwFlags=%x\n", dwFlags);
2136
2137     hres = IActiveScriptSite_GetItemInfo(site, windowW, SCRIPTINFO_IUNKNOWN, &unk, NULL);
2138     ok(hres == S_OK, "GetItemInfo failed: %08x\n", hres);
2139     ok(unk != NULL, "unk == NULL\n");
2140
2141     hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
2142     ok(hres == S_OK, "Could not get IDispatch interface: %08x\n", hres);
2143     if(SUCCEEDED(hres))
2144         IDispatch_Release(disp);
2145
2146     hres = IUnknown_QueryInterface(unk, &unknown_iid, (void**)&unk2);
2147     ok(hres == E_NOINTERFACE, "Got ?? interface: %p\n", unk2);
2148     if(SUCCEEDED(hres))
2149         IUnknown_Release(unk2);
2150
2151     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&window_dispex);
2152     ok(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres);
2153
2154     IUnknown_Release(unk);
2155     return S_OK;
2156 }
2157
2158 static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
2159                                          DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
2160 {
2161     ok(0, "unexpected call\n");
2162     return E_NOTIMPL;
2163 }
2164
2165 static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
2166                                                 IDispatch **ppdisp)
2167 {
2168     CHECK_EXPECT(GetScriptDispatch);
2169
2170     ok(!strcmp_wa(pstrItemName, "window"), "pstrItemName = %s\n", wine_dbgstr_w(pstrItemName));
2171
2172     if(!script_disp)
2173         return E_NOTIMPL;
2174
2175     *ppdisp = script_disp;
2176     return S_OK;
2177 }
2178
2179 static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface,
2180                                                        SCRIPTTHREADID *pstridThread)
2181 {
2182     ok(0, "unexpected call\n");
2183     return E_NOTIMPL;
2184 }
2185
2186 static HRESULT WINAPI ActiveScript_GetScriptThreadID(IActiveScript *iface,
2187                                                 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
2188 {
2189     ok(0, "unexpected call\n");
2190     return E_NOTIMPL;
2191 }
2192
2193 static HRESULT WINAPI ActiveScript_GetScriptThreadState(IActiveScript *iface,
2194         SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
2195 {
2196     ok(0, "unexpected call\n");
2197     return E_NOTIMPL;
2198 }
2199
2200 static HRESULT WINAPI ActiveScript_InterruptScriptThread(IActiveScript *iface,
2201         SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
2202 {
2203     ok(0, "unexpected call\n");
2204     return E_NOTIMPL;
2205 }
2206
2207 static HRESULT WINAPI ActiveScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
2208 {
2209     ok(0, "unexpected call\n");
2210     return E_NOTIMPL;
2211 }
2212
2213 static const IActiveScriptVtbl ActiveScriptVtbl = {
2214     ActiveScript_QueryInterface,
2215     ActiveScript_AddRef,
2216     ActiveScript_Release,
2217     ActiveScript_SetScriptSite,
2218     ActiveScript_GetScriptSite,
2219     ActiveScript_SetScriptState,
2220     ActiveScript_GetScriptState,
2221     ActiveScript_Close,
2222     ActiveScript_AddNamedItem,
2223     ActiveScript_AddTypeLib,
2224     ActiveScript_GetScriptDispatch,
2225     ActiveScript_GetCurrentScriptThreadID,
2226     ActiveScript_GetScriptThreadID,
2227     ActiveScript_GetScriptThreadState,
2228     ActiveScript_InterruptScriptThread,
2229     ActiveScript_Clone
2230 };
2231
2232 static IActiveScript ActiveScript = { &ActiveScriptVtbl };
2233
2234 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2235 {
2236     *ppv = NULL;
2237
2238     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
2239         *ppv = iface;
2240         return S_OK;
2241     }
2242
2243     if(IsEqualGUID(&IID_IMarshal, riid))
2244         return E_NOINTERFACE;
2245     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
2246         return E_NOINTERFACE;
2247
2248     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2249     return E_NOTIMPL;
2250 }
2251
2252 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2253 {
2254     return 2;
2255 }
2256
2257 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2258 {
2259     return 1;
2260 }
2261
2262 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2263 {
2264     CHECK_EXPECT(CreateInstance);
2265
2266     ok(!outer, "outer = %p\n", outer);
2267     ok(IsEqualGUID(&IID_IActiveScript, riid), "unexpected riid %s\n", debugstr_guid(riid));
2268     *ppv = &ActiveScript;
2269     return S_OK;
2270 }
2271
2272 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2273 {
2274     ok(0, "unexpected call\n");
2275     return S_OK;
2276 }
2277
2278 static const IClassFactoryVtbl ClassFactoryVtbl = {
2279     ClassFactory_QueryInterface,
2280     ClassFactory_AddRef,
2281     ClassFactory_Release,
2282     ClassFactory_CreateInstance,
2283     ClassFactory_LockServer
2284 };
2285
2286 static IClassFactory script_cf = { &ClassFactoryVtbl };
2287
2288 static const char simple_script_str[] =
2289     "<html><head></head><body>"
2290     "<div id=\"divid\"></div>"
2291     "<script language=\"TestScript\">simple script</script>"
2292     "</body></html>";
2293
2294 static void test_exec_script(IHTMLDocument2 *doc)
2295 {
2296     IHTMLWindow2 *window;
2297     BSTR code, lang;
2298     VARIANT v;
2299     HRESULT hres;
2300
2301     hres = IHTMLDocument2_get_parentWindow(doc, &window);
2302     ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
2303
2304     code = a2bstr("execScript call");
2305     lang = a2bstr("TestScript");
2306
2307     SET_EXPECT(ParseScriptText_execScript);
2308     hres = IHTMLWindow2_execScript(window, code, lang, &v);
2309     ok(hres == S_OK, "execScript failed: %08x\n", hres);
2310     ok(V_VT(&v) == VT_I4, "V_VT(v) = %d\n", V_VT(&v));
2311     ok(V_I4(&v) == 10, "V_I4(v) = %d\n", V_I4(&v));
2312     CHECK_CALLED(ParseScriptText_execScript);
2313     SysFreeString(lang);
2314
2315     lang = a2bstr("invalid");
2316     V_VT(&v) = 100;
2317     hres = IHTMLWindow2_execScript(window, code, lang, &v);
2318     ok(hres == CO_E_CLASSSTRING, "execScript failed: %08x, expected CO_E_CLASSSTRING\n", hres);
2319     ok(V_VT(&v) == 100, "V_VT(v) = %d\n", V_VT(&v));
2320     SysFreeString(lang);
2321     SysFreeString(code);
2322
2323     IHTMLWindow2_Release(window);
2324 }
2325
2326 static void test_simple_script(void)
2327 {
2328     IHTMLDocument2 *doc;
2329
2330     doc = create_document();
2331     if(!doc)
2332         return;
2333
2334     SET_EXPECT(CreateInstance);
2335     SET_EXPECT(GetInterfaceSafetyOptions);
2336     SET_EXPECT(SetInterfaceSafetyOptions);
2337     SET_EXPECT(SetProperty_INVOKEVERSIONING); /* IE8 */
2338     SET_EXPECT(SetProperty_HACK_TRIDENTEVENTSINK);
2339     SET_EXPECT(InitNew);
2340     SET_EXPECT(SetScriptSite);
2341     SET_EXPECT(GetScriptState);
2342     SET_EXPECT(SetScriptState_STARTED);
2343     SET_EXPECT(AddNamedItem);
2344     SET_EXPECT(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */
2345     SET_EXPECT(ParseScriptText_script);
2346     SET_EXPECT(SetScriptState_CONNECTED);
2347
2348     load_doc(doc, simple_script_str);
2349
2350     CHECK_CALLED(CreateInstance);
2351     CHECK_CALLED(GetInterfaceSafetyOptions);
2352     CHECK_CALLED(SetInterfaceSafetyOptions);
2353     CHECK_CALLED_BROKEN(SetProperty_INVOKEVERSIONING); /* IE8 */
2354     CHECK_CALLED(SetProperty_HACK_TRIDENTEVENTSINK);
2355     CHECK_CALLED(InitNew);
2356     CHECK_CALLED(SetScriptSite);
2357     CHECK_CALLED(GetScriptState);
2358     CHECK_CALLED(SetScriptState_STARTED);
2359     CHECK_CALLED(AddNamedItem);
2360     CHECK_CALLED_BROKEN(SetProperty_ABBREVIATE_GLOBALNAME_RESOLUTION); /* IE8 */
2361     CHECK_CALLED(ParseScriptText_script);
2362     CHECK_CALLED(SetScriptState_CONNECTED);
2363
2364     test_exec_script(doc);
2365
2366     if(site)
2367         IActiveScriptSite_Release(site);
2368     if(window_dispex)
2369         IDispatchEx_Release(window_dispex);
2370
2371     SET_EXPECT(SetScriptState_DISCONNECTED);
2372     SET_EXPECT(Close);
2373
2374     IHTMLDocument2_Release(doc);
2375
2376     CHECK_CALLED(SetScriptState_DISCONNECTED);
2377     CHECK_CALLED(Close);
2378 }
2379
2380 static void run_js_script(const char *test_name)
2381 {
2382     WCHAR url[INTERNET_MAX_URL_LENGTH];
2383     char urlA[INTERNET_MAX_URL_LENGTH];
2384     IPersistMoniker *persist;
2385     IHTMLDocument2 *doc;
2386     IMoniker *mon;
2387     MSG msg;
2388     HRESULT hres;
2389
2390     static const char res[] = "res://";
2391
2392     trace("running %s...\n", test_name);
2393
2394     doc = create_document();
2395     if(!doc)
2396         return;
2397
2398     set_client_site(doc, TRUE);
2399     do_advise(doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
2400
2401     lstrcpyA(urlA, res);
2402     GetModuleFileNameA(NULL, urlA + lstrlenA(res), sizeof(urlA) - lstrlenA(res));
2403     lstrcatA(urlA, "/");
2404     lstrcatA(urlA, test_name);
2405     MultiByteToWideChar(CP_ACP, 0, urlA, -1, url, sizeof(url)/sizeof(WCHAR));
2406
2407     hres = CreateURLMoniker(NULL, url, &mon);
2408     ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
2409
2410     hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistMoniker, (void**)&persist);
2411     ok(hres == S_OK, "Could not get IPersistMoniker iface: %08x\n", hres);
2412
2413     hres = IPersistMoniker_Load(persist, FALSE, mon, NULL, 0);
2414     ok(hres == S_OK, "Load failed: %08x\n", hres);
2415
2416     IMoniker_Release(mon);
2417     IPersistMoniker_Release(persist);
2418
2419     SET_EXPECT(external_success);
2420
2421     while(!called_external_success && GetMessage(&msg, NULL, 0, 0)) {
2422         TranslateMessage(&msg);
2423         DispatchMessage(&msg);
2424     }
2425
2426     CHECK_CALLED(external_success);
2427
2428     set_client_site(doc, FALSE);
2429     IHTMLDocument2_Release(doc);
2430 }
2431
2432 static void run_js_tests(void)
2433 {
2434     run_js_script("jstest.html");
2435 }
2436
2437 static BOOL init_registry(BOOL init)
2438 {
2439     return init_key("TestScript\\CLSID", TESTSCRIPT_CLSID, init)
2440         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A1-9847-11CF-8F20-00805F2CD064}",
2441                     NULL, init)
2442         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A2-9847-11CF-8F20-00805F2CD064}",
2443                     NULL, init);
2444 }
2445
2446 static BOOL register_script_engine(void)
2447 {
2448     DWORD regid;
2449     HRESULT hres;
2450
2451     if(!init_registry(TRUE)) {
2452         init_registry(FALSE);
2453         return FALSE;
2454     }
2455
2456     hres = CoRegisterClassObject(&CLSID_TestScript, (IUnknown *)&script_cf,
2457                                  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
2458     ok(hres == S_OK, "Could not register screipt engine: %08x\n", hres);
2459
2460     return TRUE;
2461 }
2462
2463 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2464 {
2465     return DefWindowProc(hwnd, msg, wParam, lParam);
2466 }
2467
2468 static HWND create_container_window(void)
2469 {
2470     static const CHAR szHTMLDocumentTest[] = "HTMLDocumentTest";
2471     static WNDCLASSEXA wndclass = {
2472         sizeof(WNDCLASSEXA),
2473         0,
2474         wnd_proc,
2475         0, 0, NULL, NULL, NULL, NULL, NULL,
2476         szHTMLDocumentTest,
2477         NULL
2478     };
2479
2480     RegisterClassExA(&wndclass);
2481     return CreateWindowA(szHTMLDocumentTest, szHTMLDocumentTest,
2482             WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
2483             300, 300, NULL, NULL, NULL, NULL);
2484 }
2485
2486 START_TEST(script)
2487 {
2488     CoInitialize(NULL);
2489     container_hwnd = create_container_window();
2490
2491     if(winetest_interactive || ! is_ie_hardened()) {
2492         if(register_script_engine()) {
2493             test_simple_script();
2494             run_js_tests();
2495             init_registry(FALSE);
2496         }else {
2497             skip("Could not register TestScript engine\n");
2498         }
2499     }else {
2500         skip("IE running in Enhanced Security Configuration\n");
2501     }
2502
2503     DestroyWindow(container_hwnd);
2504     CoUninitialize();
2505 }